DNS Record Checker

Read a zone file or a dig answer section and find the mistakes that are legal syntax: a target missing its trailing dot, a CNAME sharing a name, an MX pointing at an alias, two SPF records, and a TXT string over the 255 byte limit.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Check the records. Nothing leaves this tab.

Wanted a different tool?

  • SPF Record Checker to count the lookups inside an SPF record, because ten is a hard limit and exceeding it makes the record ignored.
  • DKIM Record Checker to read the key inside a _domainkey TXT record, which this page checks the shape of but not the contents.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

An MX with no trailing dot

It becomes mail.example.com.example.com, the zone loads, and mail stops with no error anywhere

$ORIGIN example.com.
$TTL 3600
@ IN SOA ns1.example.com. h.example.com. 1 7200 3600 1209600 300
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
@ IN MX 10 mail.example.com

A verification TXT beside a CNAME

RFC 1034 forbids a CNAME sharing a name, so which record answers depends on the resolver asking

$ORIGIN example.com.
$TTL 3600
@ IN SOA ns1.example.com. h.example.com. 1 7200 3600 1209600 300
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
www IN CNAME cdn.example.net.
www IN TXT "verification=abc123"

A second SPF record for a second sender

Two is a permerror, and a permerror means SPF is ignored entirely: adding a sender removed them all

$ORIGIN example.com.
$TTL 3600
@ IN SOA ns1.example.com. h.example.com. 1 7200 3600 1209600 300
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
@ IN TXT "v=spf1 include:_spf.google.com ~all"
@ IN TXT "v=spf1 include:mailgun.org ~all"

An MX pointing at an alias

RFC 2181 forbids it, and resolvers disagree about whether to chase it, so it works from wherever you tested

$ORIGIN example.com.
$TTL 3600
@ IN SOA ns1.example.com. h.example.com. 1 7200 3600 1209600 300
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
mail IN CNAME host.mailprovider.net.
@ IN MX 10 mail.example.com.

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Omitting the trailing dot on a target

    A name without one is relative, so the origin is appended: `mail.example.com` in an MX becomes `mail.example.com.example.com`. The zone loads, the record serves, and mail stops with no error at any stage.

    Instead:End every fully qualified name with a dot. A single label with no dots is an ordinary relative name and is usually what was meant.

  2. Adding a TXT record at a name that already has a CNAME

    RFC 1034 forbids a CNAME coexisting with any other type. Which record a resolver returns then depends on the resolver, so a domain verification added this way breaks the alias intermittently rather than obviously.

    Instead:Put the verification record at a different name, or replace the CNAME with the target's own records.

  3. Publishing a second SPF record for a second sender

    RFC 7208 makes more than one a permerror, and a permerror means SPF is ignored for the domain entirely. Adding a sender this way removes them all, including the ones that were working.

    Instead:Merge every mechanism into one v=spf1 record, watching the ten lookup limit as you go.

  4. Pointing an MX at a CNAME

    RFC 2181 section 10.3 forbids it. Some resolvers chase the alias anyway and some do not, so it works from wherever you tested it and fails elsewhere, which is the hardest kind of mail problem to reproduce.

    Instead:Point the MX at a name that has A or AAAA records directly.

  5. Raising the TTL on an address record and leaving it there

    The TTL is how long you are committed to the current answer. At a day, a failover is invisible to some clients for a day, and the moment you need it short is a day after the moment you could have shortened it.

    Instead:Keep address records at a few minutes, or drop them a day ahead of a planned change and raise them again after.

A zone that loads is not a zone that works

Almost everything that goes wrong in DNS is legal syntax. The zone loads, the records serve, and the answer is wrong. These are the ones that come back most often, and none of them produces an error at any stage.

A name without a trailing dot is relative

Write mail.example.com as an MX target inside example.com and it becomes mail.example.com.example.com. The zone loads, the record serves, mail stops, and nothing anywhere says why. This is the single most common zone file mistake, and it is not a mistake the format can catch, because a relative name is an entirely ordinary thing to write. A single label with no dots is usually intended; a name that already looks complete and is still relative is usually not.

@  IN MX 10 mail.example.com     ->  mail.example.com.example.com.
@  IN MX 10 mail.example.com.    ->  mail.example.com.

CNAME cannot share a name with anything

RFC 1034 says it and RFC 2181 repeats it: if a CNAME exists at a name, no other record type may. At the apex that makes a CNAME impossible, because SOA and NS live there, which is why every CDN has its own non-standard workaround under a different name. Add a TXT record for a domain verification at a name that already has a CNAME and you have just made both of them unreliable, in a way that depends on which resolver is asking.

www IN CNAME cdn.example.net.
www IN TXT   "verification=abc"    <- now both are undefined

An MX or NS target must not be an alias

RFC 2181 section 10.3. Some resolvers chase the CNAME anyway and some refuse, so it works from wherever you tested it and fails somewhere else. That is the worst way for a delegation or a mail route to fail, because the evidence disagrees with itself depending on who collects it.

Two SPF records is a permerror, which means neither is used

RFC 7208 section 4.5. A receiver that finds two stops evaluating SPF for the domain entirely, so publishing a second record to authorise a second sender does not add a sender, it removes them all. This happens the same way every time: a SaaS setup page says to add their TXT record, the domain already has one, and both get published.

@ IN TXT "v=spf1 include:_spf.google.com ~all"
@ IN TXT "v=spf1 include:mailgun.org ~all"     <- permerror

The TTL is a commitment, not a setting

It is how long you are stuck with the current answer. A day-long TTL on an address record means a failover is invisible to some clients for a day, and the time to shorten it is a day before you need it short, not at the moment you do. Zero is the other end and is not free: every client queries every time, and some resolvers impose a floor anyway, so it does not reliably do what it says.

A wildcard does not apply to a name that exists

A wildcard is consulted only when no record of any type exists at the queried name. Publish a single TXT record at api.example.com and the wildcard stops answering A queries for it too, so the name starts returning NODATA. The rule is per name rather than per type, which is what makes it surprising.

What this cannot see

Every check here is a property of the text you paste, because this page resolves nothing. It cannot tell you the record is actually published, that the parent delegation matches the NS set at the apex, that the MX host exists or accepts mail, that DNSSEC validates, or that the serial has been bumped since the last edit. For those, dig against the authoritative server and against a public resolver, and compare. What it does do is catch the things that are wrong before anything is published, which is the cheapest moment to find them.