Records
TXT: arbitrary text
A name to a string. SPF, DKIM, DMARC, ACME challenges, and domain-ownership tokens all ride in a TXT record.
| Type number | 16 |
| RFC | RFC 1035 §3.3.14 |
| RDATA | One or more character strings, each up to 255 bytes, concatenated by the consumer |
What it holds#
A sequence of <length><bytes> string segments. On the wire each segment is at most 255 bytes; consumers join the segments back together before parsing (display tools like dig show them as separate quoted strings). The string itself is opaque: the meaning is whatever convention the consumer adopts.
example.com. TXT "v=spf1 include:_spf.example.com ~all"When to use it#
| Purpose | Pattern |
|---|---|
| SPF | <domain> TXT "v=spf1 ..." (one record per domain max) |
| DKIM | <selector>._domainkey.<domain> TXT "v=DKIM1; k=rsa; p=..." |
| DMARC | _dmarc.<domain> TXT "v=DMARC1; ..." |
| ACME DNS-01 | _acme-challenge.<name> TXT "<base64url digest>" (RFC 8555 §8.4), added and removed by the ACME client during cert issuance |
| Domain verification | <vendor>=<token>, at the apex or a vendor-specified subdomain |
When not to use it#
- For machine-discoverable services with well-defined record types (SRV, CAA, HTTPS/SVCB, etc.): don't reach for TXT when a typed record exists.
- For ownership records that already have a typed alternative: e.g., don't put a host's address in TXT.
- For anything secret. DNS is public. Putting secrets in TXT is putting them in
digoutput for everyone. See query-types for how resolvers and caches expose every answer they receive.
dig example#
Asks for the free text published under txt.example.isitdns.net.
dig @1.1.1.1 txt.example.isitdns.net TXT; <<>> DiG 9.20.11-0ubuntu0.2-Ubuntu <<>> @1.1.1.1 txt.example.isitdns.net TXT
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32140
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;txt.example.isitdns.net. IN TXT
;; ANSWER SECTION:
txt.example.isitdns.net. 300 IN TXT "It was DNS. It is always DNS."
;; Query time: 43 msec
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
;; WHEN: Mon Sep 14 13:45:34 CDT 2026
;; MSG SIZE rcvd: 94
GO NOERROR and one quoted string
NO GO NOERROR with no answer, which means nothing is published there
Gotchas#
- 255-byte string limit. A TXT record can hold multiple 255-byte strings, but a single string is capped at 255 (RFC 1035 §3.3). Long DKIM public keys (2048-bit RSA) exceed 255 bytes and must be split as quoted-string concatenation in the zone file:
selector1._domainkey TXT "v=DKIM1; k=rsa; p=ABC..." "DEF...XYZ"Consumers join consecutive strings before parsing.
- An empty DKIM
p=means the key is revoked (RFC 6376 §3.6.1). A validly publishing selector shows a base64-encoded key there instead. - One SPF per domain. Multiple SPF TXT records at the same name is invalid per RFC 7208 §3.2; receiving servers treat it as a
permerror. Combine include rules instead:v=spf1 include:a include:b ~all. - There is no SPF record type anymore. A dedicated
SPFRRtype (99) existed during SPF's experimental phase and was discontinued; SPF data must be published as TXT only (RFC 7208 §3.1). - Case-insensitive name, case-preserving RDATA. DNS names are case-insensitive; TXT strings are case-sensitive. ACME, DKIM, etc. all care about exact bytes.
- Quoting and escaping. Spaces inside TXT must be inside quotes; backslashes escape special characters; a literal
"needs\". Most DNS-management APIs handle escaping for you. - DMARC lives at
_dmarc.<domain>, not the apex. SPF is checked at the SMTPMAIL FROMdomain (or HELO name), not inherited by subdomains: a subdomain that sends mail needs its own record. DKIM lives at<selector>._domainkey.<domain>. See email-records for full placement rules. - TTL matters for ACME. A high TTL lets resolvers cache the old token, or a stale negative answer, long after the client publishes a fresh one. Keep
_acme-challengeTTL at 60-300 seconds. - Verification tokens accumulate. Apex TXT sets grow one
<vendor>=<token>at a time and nobody deletes them. Prune tokens for services no longer in use: every TXT query for the name hauls back the whole set.
See also#
- MX: where mail is delivered
- All record types: cheat sheet
- DoH and DoT: encrypted DNS transports
- _acme-challenge check: the TXT a CA validates for DNS-01