Prufy notes
DNS ยท 12 min

The verdict

The most important function in the system. Evidence goes in, and a verdict comes out, with no network and no side effects.

The rule

A domain is verified only when all three of these hold at once. Each one is there to stop a specific way of being fooled.

(a) Someone in charge answered
At least one authoritative server responded. Otherwise we'd be trusting a cache.
(b) No one in charge disagrees
Every server that answered has the exact value. That rules out a half-applied change.
(c) A second witness agrees
A public resolver on a different network path sees it too. That defeats a forged reply.
The verification playgroundRuns the real classify and explain functions
What each server sees
ns1.example-dns.netAuthoritative
ns2.example-dns.netAuthoritative
GooglePublic resolver
CloudflarePublic resolver
The rule
Holds
(a) An authoritative server answered
2 of 2 answered
Holds
(b) Every one that answered has the exact value
2 of 2 have it
Holds
(c) A public resolver sees it too
2 of 2 see it
verified
Domain verified
Cloudflare's servers and public DNS both show your record.
Keep the record in place. We re-check it daily.
Primary action: Nothing to do
Everything on the right is computed live by packages/core. Try to predict the result before you click.
Predict it first
The provider's nameservers both have the value. Google and Cloudflare both time out. What's the verdict?

A timeout is not a no

This is the distinction most verifiers get wrong. NXDOMAIN and an empty answer are real answers: the server looked and there's nothing. A timeout or SERVFAIL means we learned nothing. Treating those as "the record isn't there" would blame the person for someone else's outage, and later, it could take away a real owner's status.

Naming every failure

When the record isn't exactly right, the classifier works out why. This is what turns "verification failed" into "you have a 1 where the code has an l".

Mismatch labEdit the value and watch the reason change
We expected
prufy-domain-verification=mfrggzdfmztwq2lknnwg23tpob
We found
prufy-domain-verification=mfrggzdfmztwq21knnwg23tpob
lookalike_characterThe first difference is character 41.

The order matters

These run top to bottom and the first match wins. A quoted old code should say "this is an older code", because that's the more useful message, so stale_token goes first.

Why the value is wrongChecked in this order
#ReasonHow it's recognised
1stale_tokenIt's a value issued earlier for this name
2extra_quotesHas quote marks, and matches once they're gone
3extra_whitespaceHas whitespace, and matches once it's gone
4wrong_prefixDoesn't start with the prefix, but ends with the code
5truncatedShorter, and a start or end of the right value
6lookalike_characterMatches if confusable characters count as equal
7different_tokenNone of the above

If nothing's at the right name, the engine goes looking in the places a mistake would have put it. That's why a check also asks about names you never told it to use.

Why the record isn't there
ReasonThe evidence
nothing_at_nameNone of the above
host_doubledFound at _prufy-challenge.example.com.example.com
wrong_nameFound at the apex, or without the underscore
not_at_authoritativePublic DNS has it, the zone's own servers don't
cname_at_nameAn authoritative server has a CNAME at the name
nxdomain_zoneNo nameservers exist for this domain at all

Why a CNAME doesn't pass

If _prufy-challenge.example.com is a CNAME pointing to a name that holds the right code, rule (b) still fails, because authoritative servers don't chase CNAMEs for you. The engine could chase it, but then the proof would live in a zone other than the one being claimed.