Introduction
DNS propagation is the time it takes for DNS changes to spread across the global DNS infrastructure. When you update a DNS record, the change isn't instant - caching resolvers worldwide hold onto the old values until their TTL (Time To Live) expires. This delay can range from minutes to days, causing confusion when your site works for you but not for others, or when monitoring shows old IP addresses long after you made changes.
Symptoms
- Your website or service works from some locations but not others
digshows different results depending on which DNS server you query- DNS checker tools show inconsistent results globally
- You recently changed A, CNAME, MX, or other records
- Users report reaching the old server after your migration
- SSL certificates fail because the domain resolves to old infrastructure
- Email continues to route to old mail servers after MX record changes
Common Causes
- High TTL values on the old records mean resolvers cache them longer
- Recursive resolvers ignoring TTL and caching longer than specified
- Negative caching of NXDOMAIN responses persisting beyond intended time
- DNS zone not properly reloaded on authoritative servers
- Changes made at registrar not yet synchronized to TLD servers
- Multiple authoritative servers out of sync
Step-by-Step Fix
- 1.Verify the change was actually made on your authoritative DNS server.
```bash # Query your domain's authoritative nameservers directly dig @ns1.yourdnsprovider.com example.com A +short
# Find your authoritative nameservers first if unknown dig example.com NS +short
# Then query each one for ns in $(dig example.com NS +short); do echo "Checking $ns:" dig @$ns example.com A +short done ```
- 1.Check the TTL values on your records to understand the expected propagation time.
```bash # Check current TTL on authoritative server dig @ns1.yourdnsprovider.com example.com A
# Look for the TTL line in the answer section # example.com. 3600 IN A 192.0.2.1 # ^^^^ # This TTL in seconds
# Check TTL on negative responses too dig @ns1.yourdnsprovider.com nonexistent.example.com # Look for SOA minimum TTL in authority section ```
- 1.Use global DNS checking tools to see propagation status worldwide.
```bash # Use dig with specific public DNS servers to check different resolvers echo "Google DNS:" && dig @8.8.8.8 example.com +short echo "Cloudflare DNS:" && dig @1.1.1.1 example.com +short echo "Quad9:" && dig @9.9.9.9 example.com +short echo "OpenDNS:" && dig @208.67.222.222 example.com +short
# Or use online propagation checkers # https://dnschecker.org # https://www.whatsmydns.net # https://viewdns.info/propagation.aspx ```
- 1.If authoritative servers show old values, force a zone reload or notify.
```bash # For BIND, force zone reload rndc reload example.com
# For PowerDNS pdns_control bind-reload-now example.com
# For Knot DNS knotc zone-reload example.com
# For NSD nsd-control reload example.com ```
- 1.Check SOA serial number to verify zone was updated after your change.
```bash # Get SOA record from authoritative server dig @ns1.yourdnsprovider.com example.com SOA
# The serial number should have increased after changes # example.com. IN SOA ns1.provider.com. hostmaster.provider.com. ( # 2026040401 ; Serial <-- This should increment # 3600 ; Refresh # 600 ; Retry # 86400 ; Expire # 3600 ) ; Minimum
# Compare serials across all authoritative nameservers for ns in $(dig example.com NS +short); do echo "SOA serial on $ns:" dig @$ns example.com SOA +short | head -1 done ```
- 1.For registrar-level changes (nameserver updates), check TLD servers directly.
```bash # Query the TLD servers for your domain's delegation dig @a.gtld-servers.net example.com NS
# Check if they reflect your new nameservers # If not, the change is still pending at the registry level
# For .com domains dig @a.gtld-servers.net yourdomain.com NS +short
# For .net domains dig @a.gtld-servers.net yourdomain.net NS +short
# For country TLDs, use their specific servers # Example for .uk dig @ns1.nic.uk yourdomain.uk NS +short ```
- 1.If you control TTL, reduce it before making future changes to speed up propagation.
```bash # Best practice: Lower TTL 24-48 hours before planned changes # Set TTL to 300-600 seconds (5-10 minutes)
# After change propagates, increase TTL back to normal (3600-86400) # This reduces load on your DNS servers
# Example BIND zone file: ; Before change - lower TTL example.com. 300 IN A 192.0.2.1
; After propagation - raise TTL example.com. 3600 IN A 192.0.2.2 ```
- 1.Clear local and upstream caches where possible to force fresh lookups.
```bash # Flush local system cache sudo systemd-resolve --flush-caches
# Restart local DNS services sudo systemctl restart systemd-resolved
# Some ISP resolvers allow cache flush via special queries # Google Public DNS: no user-accessible flush # Cloudflare: no user-accessible flush # Your own BIND resolver: rndc flush ```
- 1.Verify the change is properly formatted in your DNS zone file or control panel.
```bash # Common formatting errors that cause issues: # - Missing trailing dot on FQDNs # - Wrong record type (A vs CNAME conflict) # - IP address in wrong format (IPv6 address in A record)
# Test zone file syntax before applying named-checkzone example.com /etc/bind/zones/example.com.zone
# For online DNS providers, verify: # - Record type matches intended use # - TTL is set correctly # - No conflicting records exist ```
- 1.Document expected propagation time and communicate to stakeholders.
```bash # Create a propagation timeline based on TTLs: # - Immediate: Queries to your authoritative servers # - 0-1 hour: Users with low-TTL caching or cache misses # - 1-24 hours: Most recursive resolvers # - 24-48 hours: Resolvers ignoring TTL, negative caches
# Set up monitoring from multiple locations # Use services like: # - Pingdom # - StatusCake # - UptimeRobot # All checking DNS resolution from different regions ```
Verification
After waiting for expected propagation time, verify globally:
```bash # Check multiple geographic regions echo "US East:" && dig @8.8.8.8 example.com +short echo "US West:" && dig @8.8.4.4 example.com +short echo "Europe:" && dig @1.1.1.1 example.com +short echo "Asia:" && dig @9.9.9.9 example.com +short
# Verify all authoritative servers agree for ns in $(dig example.com NS +short); do result=$(dig @$ns example.com A +short) echo "$ns: $result" done
# Compare results - they should all match ```
Remember that some resolvers cache beyond TTL (violating DNS standards but common). For critical changes, maintain both old and new servers running until full propagation completes.