
How to Verify Domain Ownership with a TXT Record?
Almost every service that does something on behalf of your domain — sending email, issuing certificates, showing your site's search data, enabling single sign-on, claiming a GitHub organization's domain — first asks you to prove you control it. The most common way is a TXT record: the service gives you a random token, you publish it in DNS, and the service looks it up. Because only someone with access to the domain's DNS can publish records, finding the token is treated as proof of ownership.
The process is simple in principle, but it fails surprisingly often because of host-field conventions, quoting, caching, and editing the wrong DNS provider. This guide walks through how TXT verification works, how to add the record correctly, how to check it before you click Verify, and what to do with the record afterwards. If you want background on the record type itself, see what a TXT record is and what it's used for.
How TXT Verification Works
The flow is nearly identical across providers:
- The service generates a token tied to your account and the domain you're claiming — for example
google-site-verification=3fE8x...orMS=ms84721930. - You publish it as a TXT record at the name the service specifies — usually the root of the domain (
example.com), sometimes a dedicated label such as_github-challenge-myorg.example.com. - You click Verify. The service queries public DNS for TXT records at that name.
- If the token is found, the service marks the domain as verified for your account. Many services re-check periodically and revoke verification if the record disappears.
The security of this scheme rests on two things: the token is unpredictable, so nobody can publish it in advance, and only the domain's controller can change records in its authoritative zone. That's why verification must happen at whichever provider actually hosts your DNS — explained in the difference between a domain registrar and a DNS host.
Common Verification Record Formats
Each service uses its own naming pattern. These are typical examples; the exact token always comes from the service's dashboard:
| Service | Host / Name | Value format |
|---|---|---|
| Google (Workspace, Search Console) | @ | google-site-verification=TOKEN |
| Microsoft 365 | @ | MS=msNNNNNNNN |
| Meta (Facebook) Business | @ | facebook-domain-verification=TOKEN |
| Atlassian | @ | atlassian-domain-verification=TOKEN |
| GitHub organization | _github-challenge-ORG | Random code shown by GitHub |
| GitHub Pages | _github-pages-challenge-USER | Random code shown by GitHub |
| Vercel (domain in use elsewhere) | _vercel | vc-domain-verify=... |
Services that use a dedicated label (an underscore-prefixed subdomain) are being considerate: they keep the root of your domain uncluttered and avoid oversized TXT responses at the apex. Services that use the root mean you'll accumulate several TXT records at example.com over time, which is fine — DNS supports any number of TXT records at the same name.
In zone file form, a root domain with several verification tokens and an SPF record looks like this:
$ORIGIN example.com.
@ 3600 IN TXT "v=spf1 include:_spf.google.com ~all"
@ 3600 IN TXT "google-site-verification=3fE8xQ7rLm2NcVb0aZyW1kTpH4sJ9uDgEoFiR6tY5Xw"
@ 3600 IN TXT "MS=ms84721930"
@ 3600 IN TXT "facebook-domain-verification=k2l9q8w7e6r5t4y3u2i1o0p"
_github-challenge-myorg 3600 IN TXT "a1b2c3d4e5"
Each token is its own TXT record. Don't try to combine them into one string — services look for an exact match on a single record's value.
Step-by-Step: Adding a Verification TXT Record
1. Find where your DNS is hosted
Check the domain's nameservers:
dig NS example.com +short
If the answer is ada.ns.cloudflare.com and bob.ns.cloudflare.com, you edit records in Cloudflare — even if you bought the domain somewhere else. Adding the record at your registrar's DNS panel does nothing when the registrar isn't the active DNS host.
2. Copy the token exactly
Use the copy button in the service's dashboard rather than selecting text by hand. Trailing spaces, line breaks, or a missing character will cause a mismatch.
3. Create the record
In your DNS host's control panel:
- Type:
TXT - Host / Name:
@(or blank) for the root domain; for a dedicated label, enter only the label, such as_github-challenge-myorg - Value / Content: the token, usually without surrounding quotes — most control panels add them for you
- TTL: the default is fine; a lower value like 300 seconds helps if you might need to correct a mistake
If you manage DNS through an API or infrastructure-as-code, verification records are easy to automate. The Cloudflare and Route 53 versions are covered in how to set up Cloudflare DNS for your website and how to manage DNS records in AWS Route 53.
4. Confirm it's published before clicking Verify
Query the authoritative nameserver directly first, so caches can't mislead you:
dig TXT example.com @ada.ns.cloudflare.com +short
Then check what a public resolver sees, which is closer to what the service will see:
dig TXT example.com @8.8.8.8 +short
dig TXT _github-challenge-myorg.example.com @1.1.1.1 +short
On Windows:
Resolve-DnsName -Name example.com -Type TXT -Server 8.8.8.8 | Select-Object -ExpandProperty Strings
Or with nslookup on any platform:
nslookup -type=TXT example.com 8.8.8.8
When the token appears in the public resolver's output, click Verify in the service's dashboard. More dig techniques are in how to use the dig command for DNS lookups.
5. Wait for the record if needed
If you'd rather not keep re-running commands, a small loop can wait for you:
#!/usr/bin/env bash
NAME="example.com"
TOKEN="google-site-verification=3fE8xQ7rLm2NcVb0aZyW1kTpH4sJ9uDgEoFiR6tY5Xw"
until dig +short TXT "$NAME" @8.8.8.8 | tr -d '"' | grep -qxF "$TOKEN"; do
echo "Not visible yet, retrying in 30 seconds..."
sleep 30
done
echo "Token is published. You can click Verify now."
The script strips the quotes dig prints around TXT values and checks for an exact match on the token every 30 seconds. Note that tr -d only handles single-string values; verification tokens are short enough that this is always the case.
The same check in Python with dnspython, which also handles multi-string TXT values:
import time
import dns.resolver
NAME = "example.com"
TOKEN = "MS=ms84721930"
resolver = dns.resolver.Resolver()
resolver.nameservers = ["8.8.8.8", "1.1.1.1"]
def token_published():
try:
answers = resolver.resolve(NAME, "TXT")
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
return False
return any(b"".join(r.strings).decode() == TOKEN for r in answers)
while not token_published():
print("Not visible yet, retrying in 30 seconds...")
time.sleep(30)
print("Token is published.")
It queries Google and Cloudflare's resolvers, joins each record's strings, and compares the full value with the expected token.
Why Verification Fails (and How to Fix It)
- The domain was appended twice. Typing
example.comor_github-challenge-myorg.example.cominto a Host field that automatically appends the zone createsexample.com.example.com. Check withdig TXT example.com.example.com +short— if your token shows up there, fix the host field. - Literal quotes in the value. Some panels add quotes automatically. If you also type them, the record may contain
"\"google-site-verification=...\"", which doesn't match. - Edited the wrong DNS provider. The registrar's panel is not the active DNS host if nameservers point elsewhere. Always check
dig NSfirst. - Negative caching. If the service (or a resolver it uses) looked up the name before you created the record, it cached the "no such record" answer for the duration of the zone's negative TTL, taken from the SOA record. Waiting is the only fix; see what negative caching in DNS is.
- Record added at the wrong level. Verifying
shop.example.comusually requires the TXT atshop.example.com, not at the root. Read the service's instructions carefully. - An old token from a previous attempt. Generating a new token in the dashboard invalidates the old one. Make sure the published value matches the current token.
- Overly long TXT response at the apex. Domains with dozens of TXT records at the root can produce responses that need TCP, and a few verifiers handle that poorly. Clean up obsolete tokens.
- DNSSEC problems. A broken DNSSEC chain makes validating resolvers return SERVFAIL for every record, including your token. Check with
dig TXT example.com +dnssecand look at the status line.
Should You Keep or Remove the Record After Verifying?
It depends on the service:
- Keep it if the service re-verifies periodically. Google, for example, recommends leaving its verification record in place, and removing it can unverify the domain. GitHub organization verification and many SSO providers behave similarly.
- You may remove it if the service explicitly says it's only needed once. Microsoft 365's
MS=record, for instance, is only required during setup. - Remove it when you stop using a service. Old verification records reveal which vendors you use (and used), and accumulating them bloats your apex TXT response.
A good habit is to annotate tokens in your own DNS documentation or infrastructure-as-code with the service and date, so cleanup is easy later.
Security Considerations
- TXT records are public. Anyone can list the TXT records at your apex, so verification tokens leak information about your SaaS stack. That's usually acceptable, but it's one reason to prefer dedicated-label methods and to remove tokens you no longer need.
- DNS access equals account access. Anyone who can edit your zone can verify your domain with their own accounts — including email providers, certificate authorities, and identity platforms. Protect your DNS host and registrar accounts with strong authentication; how to secure DNS against attacks covers the wider picture.
- Verified domains can outlive staff. If an employee verified a domain with a personal or team account, removing their DNS access doesn't remove the verification they already completed. Review verified domains in each service periodically.
Alternatives to TXT Verification
Most services offer other methods, which can be easier when you control the website but not DNS (or vice versa):
- CNAME record — publish a unique hostname that points at a service-provided target. Common with Google and some CDNs.
- HTML file upload — place a file with a specific name and content at the root of your website.
- HTML meta tag — add a tag to your homepage's head section.
- Email to an administrative address — some certificate authorities and registrars email
admin@orhostmaster@the domain.
DNS-based verification is generally the most robust because it doesn't depend on a web server staying up or a particular page being served. The same idea, applied to SSL certificates, is the basis of the DNS-01 challenge for Let's Encrypt.
TXT Domain Verification FAQ
Yes. DNS allows any number of TXT records at the same name. Each verification token should be its own record. The only TXT type limited to one per name is SPF.
Often just a few minutes after you add the record. It can take longer if your DNS host is slow to publish changes or if the service cached a negative answer from an earlier lookup.
Usually not. Most DNS control panels add the quotes automatically. Check how existing TXT records appear in your panel and follow the same pattern.
Most providers use @ or a blank field for the root domain. Some require the full domain name. Look at how your provider shows existing root records such as MX or SPF.
No. Services look for a TXT record whose entire value matches the token. Add the token as a separate TXT record and leave your SPF record unchanged.
The service may have cached an earlier negative answer, or it may be checking a different name than the one you created. Confirm the exact host it expects, wait for the negative cache to expire, and try again.
It is as secure as access to your DNS. The token is random, and only someone who can edit your authoritative zone can publish it. Protect your DNS and registrar accounts with strong authentication.
Sometimes. Some services verify a root domain and all its subdomains at once; others require a separate record for each subdomain. Follow the instructions for the specific service.
Conclusion
TXT-based verification turns DNS into a simple proof of control: the service hands you an unpredictable token, you publish it at the name it specifies, and it looks the token up. Getting it right first time is mostly about the details — editing the provider that actually hosts your DNS, entering the host field correctly, not doubling quotes, and confirming the record is visible from a public resolver before clicking Verify.
After verification, follow each service's guidance on keeping the record, remove tokens for services you've stopped using, and treat access to your DNS as access to every account that relies on it. Done carefully, TXT verification is the most reliable way to link your domain to the services you depend on.
Here are some useful references for TXT-based domain verification:
- RFC 1035: Domain Names - Implementation and Specification — defines the TXT record type and its character-string format.
- Google Workspace Admin Help: Verify your domain for Google Workspace — Google's instructions for TXT and alternative verification methods.
- Microsoft Learn: Add a domain to Microsoft 365 — includes Microsoft's TXT verification step.
- Cloudflare Learning Center: What is a DNS TXT record? — overview of TXT records and their uses, including domain verification.
- RFC 2308: Negative Caching of DNS Queries — explains why a lookup made before the record existed can delay verification.


