← Back to Learning Hub

DNS Migration • Intermediate • 5 min read

DNS Zone Transfers: AXFR, IXFR, and Locking Them Down with TSIG

How DNS zone transfers sync secondaries: AXFR vs IXFR, what an open transfer leaks, and how to secure transfers with TSIG keys in BIND with real dig tests.

A DNS zone transfer is how a secondary (replica) nameserver copies the full set of records for a zone from the primary (master) server so that the two stay in sync. It is the oldest replication mechanism in DNS, and it is still the backbone of multi-nameserver setups. There are two flavors: AXFR, the full transfer defined in RFC 5936, and IXFR, the incremental transfer defined in RFC 1995. Left open, zone transfers hand an attacker a complete map of your infrastructure; locked down with TSIG (RFC 8945), they are a safe, efficient way to run redundant authoritative servers. This guide covers how transfers work, how they are triggered, and how to secure them.

Primary, secondary, and why transfers exist

Authoritative DNS almost always runs on more than one server for resilience. Rather than editing the same zone file by hand on every machine, you edit it once on the primary and let the secondaries pull changes automatically. The secondary is configured with the primary's IP and the zone name; the rest is driven by the SOA record and a notify-then-transfer handshake.

The sequence looks like this:

  1. You edit the zone on the primary and bump the SOA serial number.
  2. The primary sends a NOTIFY message to each secondary telling it the zone changed.
  3. The secondary queries the primary's SOA and compares serials. If the primary serial is higher, the secondary is stale.
  4. The secondary requests a transfer, AXFR or IXFR, over TCP.
  5. The primary authorizes the request (by IP and/or TSIG) and streams the records.

If no NOTIFY arrives, the secondary still polls on the SOA refresh interval, so replication is self-healing even when a notify is lost.

AXFR vs IXFR

AXFR transfers the entire zone every time, which is simple and robust but wasteful for a large zone that changed by one record. IXFR transfers only the differences since the serial the secondary already holds, which is far lighter on the wire. A server that supports IXFR keeps a journal of recent changes; if it cannot satisfy an incremental request (for example the secondary is too far behind, or the journal was lost), it falls back to a full AXFR automatically.

AspectAXFRIXFR
RFC59361995
ScopeEntire zoneOnly changes since a serial
TransportTCPPrefers UDP, falls back to TCP
Server stateNone requiredChange journal required
Best forFirst sync, recovery, small zonesFrequent small edits, large zones
FallbackNot applicableFalls back to AXFR when needed

What an open transfer leaks

If a server answers AXFR to anyone, a stranger can download your entire zone in one command. That reveals every hostname, internal-looking subdomain, mail server, staging box, and VPN endpoint you have published. It is reconnaissance gold and a frequent first step in targeted attacks. Here is what an unauthorized transfer looks like when it succeeds, which it never should from the public internet:

# Attempt a full transfer against a nameserver
dig @ns1.example.com example.com AXFR

; Transfer failed when locked down:
; Transfer failed.

; What a wide-open server would return (BAD):
example.com.        3600  IN  SOA   ns1.example.com. host.example.com. 2026101401 7200 3600 1209600 3600
example.com.        3600  IN  NS    ns1.example.com.
www.example.com.    3600  IN  A     203.0.113.10
vpn.example.com.    3600  IN  A     203.0.113.40
staging.example.com. 3600 IN  A     10.20.0.5

Locking transfers down with TSIG

The weak way to restrict transfers is an IP allow list. It helps, but source IPs can be spoofed and secondaries behind NAT or dynamic addressing break it. The strong way is TSIG, a transaction signature that adds an HMAC computed over the message using a shared secret. The primary signs its answer and the secondary verifies it (and vice versa for the request), so authentication does not depend on the source address at all.

First generate a key, then reference it in both servers. Using BIND tooling:

# Generate a shared TSIG key (HMAC-SHA256)
tsig-keygen -a hmac-sha256 xfr-key > xfr.key
cat xfr.key
key "xfr-key" {
    algorithm hmac-sha256;
    secret "aZ3k...base64...==";
};

On the primary, require the key for transfers and keep an IP guard as defense in depth:

// named.conf on the PRIMARY
include "/etc/bind/xfr.key";

zone "example.com" {
    type primary;
    file "/etc/bind/db.example.com";
    allow-transfer { key "xfr-key"; };   // TSIG required
    also-notify { 203.0.113.53; };
    notify yes;
};

On the secondary, present the same key when contacting the primary:

// named.conf on the SECONDARY
include "/etc/bind/xfr.key";

server 203.0.113.1 { keys { "xfr-key"; }; };

zone "example.com" {
    type secondary;
    file "/var/cache/bind/db.example.com";
    primaries { 203.0.113.1; };
};

Verify by running a signed transfer yourself; it should succeed with the key and fail without it:

# Should succeed, signed with the shared key
dig @203.0.113.1 example.com AXFR -y hmac-sha256:xfr-key:aZ3k...base64...==

# Same request with no key should be refused
dig @203.0.113.1 example.com AXFR
; Transfer failed.

TSIG operational notes

  • Clock sync matters. TSIG signatures carry a timestamp with a default fudge window of 300 seconds. If the primary and secondary clocks drift apart, signatures are rejected with BADTIME. Run NTP on both.
  • Protect the secret. The key file grants transfer rights. Restrict its permissions and never commit it to a public repo.
  • Rotate keys. Treat the shared secret like any credential and rotate it on a schedule, updating both ends in a brief overlap window.
  • Prefer modern algorithms. Use hmac-sha256 rather than the legacy hmac-md5.

Common failure modes

SymptomLikely causeFix
Transfer failed, REFUSEDallow-transfer excludes the secondary or key mismatchConfirm key name and secret match on both ends
BADTIME / BADSIGClock drift or wrong secretSync NTP, re-copy the secret
Secondary never updatesSOA serial not incremented or NOTIFY blockedBump serial, allow NOTIFY, check firewall on TCP 53
Always does AXFR, never IXFRJournal missing or server lacks IXFR supportEnable journaling and incremental transfers

Firewall and port notes

Zone transfers use TCP because they can exceed the size of a single UDP packet. Make sure TCP port 53 is open between primary and secondary in both directions needed for NOTIFY and transfer. Blocking TCP 53 entirely is a classic reason replication silently stalls while ordinary lookups keep working over UDP.

Once your secondaries are syncing cleanly, confirm that the records actually appear consistent from resolvers worldwide using the Valla DNS propagation checker, and browse the Valla DNS learning hub for companion guides on SOA tuning, TTL strategy, and DNSSEC, all of which interact with how and when your transfers fire.

Troubleshooting box

If results look inconsistent, compare authoritative nameservers first, then recursive resolvers by region. Capture snapshots every 10 minutes for deterministic incident timelines.

Try VallaDNS free →

Intermediate • 5 min

Glue Records: Why Your Nameservers Need Them

Glue records break the circular lookup when nameservers live inside the domain they serve. See in-bailiwick rules, dig referrals, and how to set glue safely.