Zone Transfer Errors: Causes and Fixes

"Transfer failed", REFUSED, NOTAUTH, BADKEY, timeouts, and a serial that never updates: what each one means and how to fix it on your primary.

How a zone transfer works

Most errors make sense once you know the four steps:

  1. You change the zone on your primary and raise the SOA serial.
  2. Your primary sends a NOTIFY to the secondary over UDP port 53.
  3. The secondary asks your primary for the SOA record and compares the serial with its own copy.
  4. If your serial is higher, the secondary requests the zone with IXFR or AXFR over TCP port 53.

Without a NOTIFY, the secondary still checks the SOA on its own schedule (the refresh interval in your SOA record). A missing NOTIFY makes updates slow. It does not stop them.

Test the transfer yourself

Run this from a host that your primary allows to transfer. Replace 192.0.2.1 with the address of your primary.

terminal
# without TSIG
$ dig AXFR example.ch @192.0.2.1
 
# with TSIG
$ dig AXFR example.ch @192.0.2.1 -y hmac-sha256:example-transfer:<secret>

A good answer starts and ends with the SOA record. Anything else is one of the errors below. Your primary's log usually names the reason more precisely than the client does.

"Transfer failed" or REFUSED

The primary received the request and said no. The requesting address, or the missing key, is not in the primary's transfer permission. On BIND, the log shows a line with zone transfer ... denied.

  • Add every transfer address of your secondary to the permission. For hiddenprimary.ch, those are four addresses: two hosts, each with IPv4 and IPv6. See Getting Started.
  • If you use TSIG, make sure the permission names the key, not only addresses.
  • Check that you changed the right zone block. A server with views (split DNS) can hold the zone twice.
  • Check that the zone loaded at all. A zone with a syntax error is not served, and the primary refuses the transfer.

Connection timeout

The request never reached the DNS server, or the answer never came back. Almost always a firewall or NAT:

  • Open TCP port 53 inbound from the transfer addresses. Zone transfers do not use UDP. A firewall that only allows UDP 53 lets the SOA check through and blocks every transfer.
  • Behind a router, forward TCP and UDP port 53 to the primary.
  • Check the address you gave the secondary. It must be the public address the secondary can reach, not an internal one.

Connection refused

The address is reachable, but nothing listens on port 53 there. The DNS server either is not running, or it listens only on some addresses (for example only on localhost or an internal interface). Configure it to listen on the address you gave the secondary, for both IPv4 and IPv6 if you use both.

NOTAUTH or NOTIFY is ignored

NOTAUTH means the receiver does not accept this message from you. For a NOTIFY, it means the secondary did not recognise the sender as the zone's primary:

  • The NOTIFY comes from a different address than the one you gave the secondary. This happens when a server has several addresses and picks another one as the source. Set the source address explicitly, or add the other address as a primary.
  • The zone uses TSIG, but the NOTIFY is sent without the key. In BIND, name the key in also-notify: also-notify { 159.69.29.118 key "example-transfer"; };.

A refused NOTIFY only delays updates until the next refresh. Fix it anyway: the refresh interval can be hours.

BADKEY, BADSIG, BADTIME (TSIG errors)

ErrorMeaningFix
BADKEYThe receiver does not know a key with this name and algorithm. Use exactly the same key name on both sides, and the same algorithm, for example hmac-sha256 on both.
BADSIGThe key name is known, but the signature does not match. The secrets differ. Copy the secret again, completely, including a trailing =.
BADTIMEThe clocks of the two servers are too far apart. TSIG allows about five minutes of difference. Run NTP on your primary.

The TSIG guide shows the key configuration for the common servers.

The transfer works, but changes do not arrive

  • The serial did not go up. The secondary compares serials and keeps its copy when yours is not higher. Raise the serial on every change.
  • The server did not load your edit. After editing a file, reload the zone. On BIND, a zone that accepts dynamic updates ignores the edited file on rndc reload and still reports success. Use rndc freeze, edit, then rndc thaw.
  • You compare the wrong thing. If the secondary signs the zone with DNSSEC, it publishes its own serial. Compare a record you changed, not the serial.
  • The zone's own NS records still name the old provider. Resolvers then keep asking the old servers. We report this as NS_MISSING_OURS or NS_INCOMPLETE_OURS; the migration guide explains the fix.

"The primary's serial is lower than ours"

The secondary holds a copy with a higher serial than your primary now has. This happens when a zone was rebuilt from an old backup, or when the serial format changed, for example from a counter to a date. The secondary then refuses every update, because a lower serial counts as older.

Raise the serial on your primary above the one the secondary holds. If that is not possible, contact us and we reset the zone.

What the portal shows

The zone overview shows the last error we saw. The most common messages:

MessageWhat to check
zone has never loaded from the primaryThe first transfer never worked: permission, firewall, or a wrong primary address. Start with the test above.
zone expires in … — transfers from the primary are failingTransfers stopped working. We keep serving the last copy until the SOA expire time runs out. Fix it before then.
the primary's serial … is lower than oursSee the section above.

After you fix the cause, press Trigger Transfer on the zone page to test at once instead of waiting for the next refresh.

Next Steps