Skip to content
AZ Tools

DNS Zone File Validator

A zone file looks like a table and behaves like a program. The owner name of a record can be inherited from the line above it simply because the line starts with a space; a name without a trailing dot has the current origin appended to it, so `www IN CNAME example.com` quietly becomes example.com.example.com.; a $ORIGIN or $TTL directive halfway down the file changes the meaning of everything below it; and a record spread across several lines inside parentheses is one record no matter how it is indented. This validator parses the file the way RFC 1035 section 5 defines it — quoted strings, comments, backslash escapes, parenthesised continuations, the BIND 8 TTL units and the owner-inheritance rule — and then shows you the zone it actually describes: every record with its owner fully qualified, the TTL a server would really serve, and a count per type. On top of the parse it runs the checks a parser has no reason to make. It flags a name written without a trailing dot that will therefore be suffixed with the origin; a CNAME sharing a name with any other record, which RFC 1034 forbids and which most servers refuse to load at all; a CNAME chain that loops; an MX, NS or CNAME target inside the zone with no address record behind it; a TTL of zero; a duplicate record; a name outside the origin, which a loader drops without a word; and an SOA whose serial is not date-based or whose negative-cache TTL is long enough to keep a typo alive for days. Each finding names the line it came from, and so does every parse error, together with the line itself. What it cannot tell you is whether the zone is true. It never queries the network, so it does not know that the address you gave a host is the address that host has, that a nameserver you delegate to is actually answering, or that the TXT record you pasted matches the one your provider expects. It also checks a file, not a running zone: a record served from a database, a wildcard expanded at query time and a CNAME that lives in a different zone are all outside its view. For the live answers use a DNS lookup tool; use this one before the file is loaded, when a missing dot still costs nothing.

The zone parses

Every record below is shown with its owner name fully qualified and with the TTL a server would really serve.

Records

14

Names

7

Types

8

Findings

5

Directives in force

$ORIGIN at the end of the file

example.com.

Default TTL

3600 (from $TTL)

SOA record

Primary name server

ns1.example.com.

The MNAME: the master a secondary transfers from, and the server NOTIFY is sent from.

Responsible mailbox

hostmaster@example.com

The RNAME, written as a domain name; the first label is the local part of the address.

Serial

2026090301

A secondary only transfers the zone when this number goes up, compared as a 32-bit serial.

Refresh

7200 (2h)

How often a secondary re-checks the serial when a NOTIFY does not reach it.

Retry

3600 (1h)

How long a secondary waits before trying again after a refresh has failed.

Expire

1209600 (2w)

After this long with no successful transfer a secondary stops answering for the zone.

Negative cache TTL

300 (5m)

Since RFC 2308 this field caps how long an NXDOMAIN answer is cached; it is no longer the zone default TTL.

Findings
  • ErrorLine 19Written without a trailing dot, so the origin is appendedexample.com → example.com.example.com.
  • ErrorLine 20Written without a trailing dot, so the origin is appendedshops.myprovider.net → shops.myprovider.net.example.com.
  • WarningLine 19The target is inside this zone but has no address recordCNAME → example.com.example.com.
  • WarningLine 20The target is inside this zone but has no address recordCNAME → shops.myprovider.net.example.com.
  • WarningLine 21A TTL of zero forbids caching this record at allold.example.com. A
Records per type
A 5CNAME 2NS 2AAAA 1CAA 1MX 1SOA 1TXT 1
Records
OwnerTTLClassTypeData
example.com.3600INSOAns1.example.com. hostmaster.example.com. 2026090301 7200 3600 1209600 300
example.com.3600INNSns1.example.com.
example.com.3600INNSns2.example.com.
example.com.3600INA192.0.2.10
example.com.3600INAAAA2001:db8::10
example.com.3600INMX10 mail.example.com.
example.com.3600INTXT"v=spf1 mx -all"
example.com.3600INCAA0 issue "letsencrypt.org"
ns1.example.com.3600INA192.0.2.1
ns2.example.com.3600INA192.0.2.2
mail.example.com.3600INA192.0.2.3
www.example.com.3600INCNAMEexample.com.example.com.
shop.example.com.3600INCNAMEshops.myprovider.net.example.com.
old.example.com.0INA192.0.2.9

Everything runs in your browser: the file is never uploaded, and nothing is looked up over the network.

How to use

  1. Paste the zone file into the box. It stays in the browser — nothing is uploaded and no lookup is made.
  2. Leave the origin box empty if the file starts with $ORIGIN. If it does not, type the zone name there, exactly as the server configuration names it, because the same file means different things under different origins.
  3. If the file does not parse, read the line number and the line printed under it: the error is reported where the parser gave up, which for a stray closing quote or an unclosed parenthesis can be one line after the mistake.
  4. Check the SOA panel: the responsible mailbox is shown as an email address, and each timer is shown in seconds with a human-readable form beside it.
  5. Work through the findings from top to bottom — errors first, then warnings, then notes — and use the line number on each one to jump back to the offending record.

Frequently asked questions

Why did my CNAME turn into example.com.example.com.?
Because the target had no trailing dot. In a master file every name is relative to the current origin unless it ends in a dot, and the parser has no way to know that "example.com" was meant as a fully qualified name rather than as a host called example.com inside your zone. The rule applies to every name field, not just CNAME: MX targets, NS targets, SRV targets and the SOA's primary server all get the origin appended the same way. The habit that avoids it is to write every name that leaves your zone with the dot, and to write the ones inside it as bare labels.
The file has no $TTL. Is that an error?
Not necessarily. RFC 1035 had no $TTL directive at all; RFC 2308 added it and required it, but most parsers, dnspython included, still fall back to the SOA's minimum field for any record that has no TTL of its own — and if the SOA is the first record, its own TTL comes from its minimum too. A record with no TTL that appears before the SOA and before any $TTL is a real error, since there is nothing to inherit from. This tool reports the fallback as a note and tells you which value ended up being used.
Two records with the same name and type have different TTLs. Which one wins?
Neither, really. All the records of one name and type form a single RRset, and an RRset is served with one TTL; when a file gives several, a loader keeps the smallest and there is no warning in the log. That means a 60-second record next to a 86400-second record of the same name and type makes both of them 60 seconds, which is usually the opposite of what the author intended. The tool shows the effective TTL in the table and flags each line whose written TTL was overridden.
Why is a record with a name outside the zone missing from the table?
Because it is missing from the zone. A loader only keeps records whose owner name is at or below the zone origin; anything else is out-of-zone data, and it is discarded silently rather than rejected. This is how a PTR record pasted into a forward zone, or a leftover record from a previous origin after a $ORIGIN line, disappears without the file ever failing to load. The tool lists each dropped name as a finding so the disappearance is at least visible.
Can a TXT record be longer than 255 characters?
The record can; a single string inside it cannot. A character-string in DNS carries a one-octet length, so 255 is the hard ceiling, and a longer quoted string is a syntax error rather than a truncation. The way to write a long DKIM or SPF value is as several quoted chunks on one record — "part one" "part two" — which the server concatenates with nothing in between. Resolvers hand the pieces to the application separately, so a value split at an arbitrary point still reassembles correctly, but only if the pieces are in the right order.
Does a valid zone file mean DNS will work?
No. Parsing proves the syntax, and the extra checks here prove some internal consistency, but nothing in a file can tell you that the parent zone delegates to your nameservers, that those servers have loaded this version, that the addresses are reachable, or that the serial you bumped is actually higher than the one your secondaries already hold. Serial comparison in particular is 32-bit sequence-space arithmetic, so a serial that "went down" because someone typed a date wrong can leave secondaries stuck on the old zone until the number wraps far enough round.

Related tools