Zone Files and Zone Transfers

Zone file format and syntax, SOA record deep dive, AXFR and IXFR transfers, TSIG authentication, and modern zone management.

Before cloud DNS providers with APIs, before databases and dynamic updates, there were zone files. Plain text files that defined every record in a zone. And honestly? They’re still everywhere.

Understanding zone file format isn’t just historical knowledge — it’s practical. You’ll encounter zone files in BIND configurations, in debugging output, in migration exports, and in the RFCs themselves.

Zone File Format and Syntax

Zone files follow the “master file format” defined in RFC 1035 §5. It’s been stable since 1987.

Basic Structure

$TTL 3600                    ; Default TTL for the zone
$ORIGIN example.com.         ; Base domain for relative names

; SOA record (required, exactly one)
@    IN  SOA  ns1.example.com. admin.example.com. (
             2024012801 ; Serial
             3600       ; Refresh (1 hour)
             600        ; Retry (10 minutes)
             604800     ; Expire (1 week)
             300        ; Minimum (negative cache TTL)
)

; Nameserver records
@    IN  NS   ns1.example.com.
@    IN  NS   ns2.example.com.

; Address records
@         IN  A      93.184.216.34
www       IN  A      93.184.216.34
mail      IN  A      93.184.216.35

; Mail routing
@         IN  MX     10 mail.example.com.

; Text records
@         IN  TXT    "v=spf1 mx -all"

Key Syntax Elements

Comments: Anything after ; is a comment

Directives: Lines starting with $ are directives

  • $TTL: Default TTL for records that don’t specify one
  • $ORIGIN: The domain appended to relative names
  • $INCLUDE: Include another file

@ symbol: Represents the current $ORIGIN (zone apex)

Relative vs absolute names:

  • www (no trailing dot) → relative → becomes www.example.com.
  • mail.example.com. (trailing dot) → absolute → used as-is

Parentheses: Allow multi-line records (whitespace is ignored inside)

Record Format

name    ttl    class    type    rdata
www     3600   IN       A       93.184.216.34

If ttl is omitted, uses the $TTL default. If name is omitted, uses the previous record’s name (continuation).

Common Gotchas

Forgetting the trailing dot:

; WRONG: This creates mail.example.com.example.com.
mail    IN  CNAME   mail.example.com

; RIGHT: This creates the intended CNAME
mail    IN  CNAME   mail.example.com.

Relative MX/NS targets:

; WRONG: "mail" becomes mail.example.com., then that + origin = double suffix
@       IN  MX  10  mail

; WRONG: Even worse — a bare name in the rdata field
@       IN  NS  ns1

; RIGHT: Always use FQDNs for MX and NS targets
@       IN  MX  10  mail.example.com.
@       IN  NS      ns1.example.com.

SOA Record Deep Dive

The Start of Authority record is required at the zone apex. It defines zone metadata and controls replication behavior.

example.com. IN SOA ns1.example.com. hostmaster.example.com. (
    2024012801  ; Serial
    3600        ; Refresh
    600         ; Retry
    604800      ; Expire
    300         ; Minimum
)

Field-by-Field

Field Example Meaning Recommendations
MNAME ns1.example.com. Primary nameserver Must be a valid NS for the zone
RNAME hostmaster.example.com. Admin email (@ → .) hostmaster@ or dns-admin@
Serial 2024012801 Zone version Increment on every change
Refresh 3600 Secondary check interval 1-24 hours typical
Retry 600 Retry after failed refresh 1/4 to 1/10 of refresh
Expire 604800 When to stop serving if primary unreachable 1-4 weeks
Minimum 300 Negative cache TTL 60-3600 seconds

Serial Number Conventions

The serial number must increase with every zone change. Secondary servers compare serials to detect updates.

YYYYMMDDnn format (recommended):

2024012801  ; January 28, 2024, revision 01
2024012802  ; January 28, 2024, revision 02
2024012901  ; January 29, 2024, revision 01

This format is human-readable and naturally sorts correctly. The nn suffix allows up to 100 changes per day.

Unix timestamp: Some systems use epoch seconds. Works but isn’t human-readable.

Simple increment: Just add 1 each time. Works but loses date context.

What If Serial Goes Backward?

If you accidentally decrease the serial (e.g., restoring a backup), secondaries won’t see an update — they think they already have a newer version.

Fixes:

  • Jump the serial to a value higher than any previous (e.g., use current YYYYMMDDnn)
  • Use serial arithmetic (RFC 1982) — but this is complex and error-prone
  • Manually reset all secondary servers

Zone Transfers

Zone transfers replicate zone data from primary to secondary servers. Two protocols exist: AXFR and IXFR.

AXFR: Full Zone Transfer

AXFR (Authoritative Transfer) transfers the entire zone. Defined in RFC 5936.

How it works:

  1. Secondary connects to primary via TCP port 53
  2. Secondary sends AXFR query
  3. Primary sends all records, bracketed by SOA records
  4. Secondary replaces its entire zone data with the new version
Secondary → Primary: AXFR query for example.com
Primary → Secondary:
  SOA (serial 2024012801)
  NS ns1.example.com.
  NS ns2.example.com.
  A record for @
  A record for www
  ... all records ...
  SOA (serial 2024012801)  ← marks end of transfer

When AXFR is used:

  • Initial setup of a new secondary
  • When the secondary’s serial is too far behind (gap in IXFR chain)
  • When explicitly requested by administrator

IXFR: Incremental Zone Transfer

IXFR (Incremental Transfer) sends only changes since a specified serial. Defined in RFC 1995.

How it works:

  1. Secondary includes its current serial in the IXFR query
  2. Primary sends a sequence of deletions and additions
  3. Secondary applies changes incrementally
Secondary → Primary: IXFR for example.com, I have serial 2024012800
Primary → Secondary:
  SOA (serial 2024012801)  ← new serial
  SOA (serial 2024012800)  ← delete section for old serial
  A www 93.184.216.34      ← record to delete
  SOA (serial 2024012801)  ← add section for new serial
  A www 93.184.216.35      ← record to add
  SOA (serial 2024012801)  ← end marker

IXFR benefits:

  • Far less data transferred for small changes
  • Faster synchronization
  • Lower bandwidth usage

IXFR limitations:

  • Primary must keep history of changes (journal)
  • If changes are too old, falls back to AXFR

Refresh and Retry

Secondaries poll primaries based on SOA timing values:

  1. Secondary waits refresh seconds
  2. Secondary queries primary’s SOA
  3. If serial increased, request IXFR/AXFR
  4. If primary unreachable, retry every retry seconds
  5. After expire seconds unreachable, stop serving the zone

Modern DNS also supports NOTIFY (RFC 1996): primaries push notifications to secondaries immediately after zone changes, eliminating wait time.

TSIG: Authenticating Transfers

Zone transfers are sensitive — you don’t want arbitrary clients downloading your entire zone or, worse, sending fake updates. TSIG (Transaction Signature) provides authentication.

How TSIG Works

TSIG uses shared secret keys and HMAC algorithms to sign DNS messages (RFC 8945).

  1. Both primary and secondary are configured with the same key
  2. Requests include a TSIG record with an HMAC signature
  3. Server verifies the signature before responding
  4. Responses are also signed

BIND configuration example:

key "xfer-key" {
    algorithm hmac-sha256;
    secret "base64-encoded-secret==";
};

TSIG for Dynamic Updates

TSIG also authenticates dynamic DNS updates — allowing authorized clients to modify zone records without editing zone files.

# nsupdate with TSIG authentication
nsupdate -k /path/to/tsig.key << EOF
server ns1.example.com
zone example.com
update delete test.example.com A
update add test.example.com 300 A 192.0.2.100
send
EOF

Modern Zone Management

Zone files are battle-tested, but modern operations often use other approaches:

API-Driven DNS Providers

Cloudflare, Route 53, Google Cloud DNS, and others expose HTTP APIs:

# Add a record via API
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dns_records" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"type":"A","name":"test","content":"192.0.2.100","ttl":300}'

Benefits:

  • Immediate propagation (no zone transfer delay)
  • Built-in redundancy and anycast
  • Version control through API audit logs

Infrastructure as Code

Tools like Terraform, Pulumi, and OctoDNS manage DNS as code:

# Terraform example
resource "cloudflare_record" "www" {
  zone_id = var.zone_id
  name    = "www"
  value   = "93.184.216.34"
  type    = "A"
  ttl     = 300
}

Benefits:

  • Changes reviewed in pull requests
  • Automatic deployment pipelines
  • State tracking and drift detection

Git-Managed Zone Files

Some operations keep traditional zone files but manage them with Git:

# Edit zone file
vim db.example.com

# Increment serial (critical!)
# Commit and push
git commit -am "Add new A record for api.example.com"
git push

# CI/CD deploys to DNS servers

This combines zone file portability with modern version control.

When to Use Each

Approach Best For
Raw zone files Self-hosted BIND/NSD, maximum control
API providers Easy management, built-in HA, low maintenance
Terraform/IaC Multi-provider, reproducible infrastructure
Git + zone files Self-hosted with version control

Zone File Utilities

Useful tools for working with zone files:

# Validate zone file syntax
named-checkzone example.com db.example.com

# Convert AXFR to zone file
dig @ns1.example.com example.com AXFR > example.com.zone

# Pretty-print and sort
ldns-read-zone db.example.com

# Diff two zone versions
diff <(ldns-read-zone old.zone) <(ldns-read-zone new.zone)

Key Takeaways

  • Zone file format is plain text, defined in RFC 1035, still widely used
  • $ORIGIN and trailing dots control relative vs absolute name interpretation
  • SOA records define zone metadata: serial, refresh, retry, expire, minimum
  • Serial numbers must increment on every change — YYYYMMDDnn is the standard convention
  • AXFR transfers entire zones; IXFR transfers only changes
  • TSIG authenticates transfers and dynamic updates using shared secrets
  • Modern approaches include APIs, Terraform, and Git — but zone files remain the interchange format

Even if you never hand-edit a zone file, understanding the format helps you read dig output, debug issues, and migrate between providers. In the final chapter, we’ll go even deeper: the DNS protocol itself.