A CAA (Certification Authority Authorization) record is a DNS record that tells the world which certificate authorities are allowed to issue TLS/SSL certificates for your domain. Before a public CA such as Let's Encrypt, DigiCert, or Google Trust Services signs a certificate, it is required to look up your CAA records and refuse the request if your policy does not list it. In short, a CAA record turns DNS into an access-control list for certificate issuance, and it is one of the cheapest guardrails you can add against mis-issued certificates.
CAA is defined in RFC 8659 and the checking behavior is mandatory for every publicly trusted CA under the CA/Browser Forum Baseline Requirements. If you publish no CAA record at all, every CA is implicitly permitted, which is the historical default. The moment you publish even one record, you switch to an allowlist model where anything not named is denied.
What a CAA record looks like
Every CAA record has three parts: a flags byte, a property tag, and a quoted value. The format in a zone file is simple and consistent across providers.
example.com. 3600 IN CAA 0 issue "letsencrypt.org"
example.com. 3600 IN CAA 0 issuewild "digicert.com"
example.com. 3600 IN CAA 0 iodef "mailto:security@example.com"
Reading left to right: the 0 is the flags field, issue is the property tag, and the quoted string is the value. The flags byte currently defines a single meaningful bit, the "critical" flag (value 128). If a CA sees a critical flag on a tag it does not understand, it must refuse to issue. For the standard tags below you almost always leave flags at 0.
The property tags you will actually use
| Tag | Controls | Example value |
|---|---|---|
| issue | Issuance of non-wildcard certificates (and wildcards if no issuewild is present) | "letsencrypt.org" |
| issuewild | Issuance of wildcard certificates only; overrides issue for wildcards | "digicert.com" |
| iodef | Where a CA should report an issuance request that violates your policy | "mailto:security@example.com" |
Two special cases are worth memorizing. To forbid all issuance outright, publish 0 issue ";". The lone semicolon means "no CA is authorized." To allow a CA but restrict it to a specific account or validation method, some CAs accept parameters after the domain, for example 0 issue "letsencrypt.org; validationmethods=dns-01".
How CAs check your records
CAA checking climbs the DNS tree. When a CA validates a request for shop.example.com, it looks for CAA records at that exact name first. If none exist, it strips a label and tries example.com, and keeps walking up toward the root until it finds a record set or runs out of labels. The first set it finds wins, and no further climbing happens.
- Query CAA for
shop.example.com. Found records? Use them and stop. - Nothing there? Query CAA for
example.com. - Still nothing? The tree-climb ends and all CAs are permitted.
This means a single CAA record at your apex protects every subdomain that does not define its own policy. It also means a stray CAA record on a subdomain can silently override your apex policy for that branch, so audit subdomains before you assume the apex covers them.
Checking your own records with dig
You can confirm what the world sees with a single query. The +short output keeps it readable.
$ dig example.com CAA +short
0 issue "letsencrypt.org"
0 issuewild "digicert.com"
0 iodef "mailto:security@example.com"
$ dig CAA cloudflare.com +short
0 issue "comodoca.com"
0 issue "digicert.com; cansignhttpexchanges=yes"
0 issue "letsencrypt.org"
0 issuewild "comodoca.com"
0 issuewild "digicert.com; cansignhttpexchanges=yes"
If you get no output, you have no CAA record at that name, and the CA will keep climbing. To watch the tree-climb yourself, query each parent label in turn and see where records first appear.
Common mistakes that block valid certificates
CAA is powerful enough to lock you out of your own renewals if you get the value wrong. The failures below account for most support tickets.
- Using the wrong CA domain string. The value must be the exact issuer domain the CA publishes, not a marketing name. Let's Encrypt is
letsencrypt.org, not "lets encrypt" or a reseller name. Check your CA's documentation for the precise string. - Forgetting issuewild. If you only publish
issue, wildcards fall back to that policy. But if you publish anyissuewildrecord, it fully governs wildcards and anissueentry no longer applies to them. - Listing a CA you no longer use. If you migrate from DigiCert to Let's Encrypt but leave the old
issuerecord, renewals through the new CA will fail because it is not authorized. - A rogue CAA on a subdomain. Because the first match wins, a leftover record on
wwwor a staging host can block issuance there even when the apex is correct. - Adding a critical flag by accident. Setting flags to
128on a tag the CA does not recognize forces a hard refusal.
A sensible rollout plan
Treat CAA like any other change that can break production: stage it, verify it, then tighten it.
- Inventory every CA that currently issues for you, including CDN and load-balancer certificates you may not manage directly.
- Publish
issuerecords for each legitimate CA, plus aniodefaddress you actually monitor. - Wait out your TTL and confirm with
digthat resolvers return the full set. - Run a test renewal or a fresh issuance to prove nothing is blocked.
- Only after that, remove any CA you want to retire from the list.
Keep the TTL moderate, often one hour, so a mistake can be corrected quickly without a long propagation wait. CAA is checked at issuance time, not on every TLS handshake, so you do not need an aggressively short TTL for day to day operation.
CAA and DNSSEC
CAA does not require DNSSEC, and a CA will honor unsigned CAA records. That said, CAA tells a CA what your policy is, and DNSSEC lets the CA trust that the answer was not tampered with in transit. Many CAs give DNSSEC-signed zones more weight and some use it to resist spoofed CAA responses. If you care enough to publish CAA, signing the zone is the natural next step for a complete issuance-security posture.
Verify before you trust it
CAA is a quiet record that only shows its teeth at issuance time, which is exactly when a mistake hurts most. After any change, check that your records have propagated and that every live resolver returns the policy you intended. You can confirm global propagation with the Valla DNS propagation checker, and if you want to layer in signing or understand the records that sit alongside CAA at your apex, the Valla DNS /learn/ guides on DNSSEC and TXT verification records are good next stops.