CAA Record Checker: Find Gaps Before Renewal
How the CAA checker finds the record a CA uses, compares it with Certificate Transparency history, and flags renewal risks and partial account binding.
Control Plane Labs Staff
Published October 12, 2026
CAA has been mandatory for public CAs since September 2017, when the CA/Browser Forum passed Ballot 187. Every CA must look up the record before it issues. The trouble starts later, when the record and the way you actually get certificates drift apart. A DNS lookup tells you what the record says today. It cannot tell you whether that matches the CAs that issued for you last quarter. That comparison is what this tool adds.
Step 1: find the record that applies
A CA does not just query the exact name. RFC 8659 defines the “relevant resource record set” as the first non-empty CAA set found by starting at the name and removing one label at a time. For api.eu.example.com, a CA checks api.eu.example.com, then eu.example.com, then example.com, then com, and stops at the first name that has CAA.
Two consequences catch people out:
- A record on the apex governs every subdomain that has none of its own. One
issueline onexample.comdecides who can issue for hundreds of hostnames. - A single CAA record on a subdomain replaces the apex policy for that subtree completely. Nothing is merged from the parent.
The checker queries each name in turn through a public DNS-over-HTTPS resolver and shows which one supplied the record. When the answer comes from a parent, the result says so.
DNS aliases add a third rule. If a name is a CNAME, the resolver returns the CAA records of the target, and Cloudflare’s CAA documentation warns that a restrictive record on a CNAME target “take[s] precedence” over your own zone. The tool sees the same answer a CA would.
Step 2: parse what the record allows
Each record has a flags byte, a tag and a value. The checker handles the tags RFC 8659 defines:
issuelists a CA allowed to issue any certificate. Without anissuewildrecord, it also covers wildcards.issuewildoverridesissuefor wildcard certificates only.iodefgives CAs an address for reporting requests that violate your policy.- A value of
";"names no CA, so it forbids issuance for that tag.
Values are additive. As Let’s Encrypt’s CAA documentation puts it, “if any one of those records allows the CA to issue, then it is allowed.”
The checker also flags a critical flag (128) on a tag it does not recognize. RFC 8659 tells a CA to refuse issuance when it meets a critical tag it does not understand, so a stray flag can block every renewal.
Step 3: compare with Certificate Transparency
Every certificate from a public CA is published to the append-only logs defined in RFC 6962. The checker reads one page of certificates for the exact name from CertIndex, skips precertificates so each certificate counts once, and groups the last 13 months by issuing organization. It then maps each organization to the CAA identifiers that CA documents (for example letsencrypt.org, pki.goog, digicert.com or amazon.com) and reports:
- “Issued here but not allowed now.” The most important finding. CAA is only evaluated at issuance, so a record edited after your last renewal does not affect the live certificate. It breaks the next one. Managed platforms make this easy to miss. Google Cloud’s managed-certificate documentation says that if CAA names only one of
pki.googandletsencrypt.org, “only that CA is used to create and renew your certificate.” - Allowed but unused. CAs that are on the list but issued nothing for this name in the window. One backup CA is a reasonable hedge against an outage. Five usually means a platform wrote the list. Cloudflare, for instance, adds its Universal SSL CAs automatically once a zone has any CAA record, and those additions do not appear in its dashboard.
- Unmapped issuers. CAs the tool has no identifier for. Look the identifier up in section 4.2.1 of that CA’s CP/CPS.
Wildcard certificates are checked separately against issuewild when one exists. If CT shows no wildcards at all, the tool suggests adding issuewild ";".
CT history is a lower bound. The tool reads a single page, and an index can lag the logs. Treat “unused” as a prompt to check, not proof. The CT lookup shows the underlying records.
Step 4: check account binding
A plain allowlist does not stop someone who controls your DNS. They can pass domain validation with any allowed CA. RFC 8657 closes that gap with two parameters on issue and issuewild values. accounturi limits issuance to one ACME account, and validationmethods limits how the CA may verify control. Let’s Encrypt describes the purpose plainly: account binding ensures “someone who temporarily hijacks your domain, but doesn’t have access to your ACME Account key, can’t issue malicious certificates.”
The checker reports one of three states:
- Every allowed value is bound. Good. A hijacker without your account key fails the CAA check.
- Binding is partial. Some values are bound and others are not. Because values are additive, the unbound value is an open door, and the binding has no effect. In our survey of 60 developer sites, three of the four domains that used binding had this problem.
- No binding. Common, and worth fixing on any domain an attacker would bother to target.
Step 5: use the suggested record
The tool ends with a starting-point record set built from the CAs seen in CT. It writes one issue line per CA with an accounturi=ACCOUNT placeholder. It adds issuewild ";" unless wildcards were issued, and an iodef contact at security@ your domain. Before publishing:
- Replace
ACCOUNTwith your ACME account URL. Certbot stores it in the account directory under/etc/letsencrypt/accounts. Remove the parameter for CAs you do not reach over ACME. - Add every platform that requests certificates for you: CDNs, load balancers and SaaS custom domains.
- Lower the record’s TTL before the change and confirm the next renewal succeeds.
Limits
The checker queries one public resolver. A CA’s resolver could see a different answer during propagation or a split-horizon setup. It reads CT for the exact name you enter, so check the hostnames you actually serve, not only the apex. And it cannot see private CAs, which never write to public logs.
Read next
- CAA records on 60 developer sites: 2026 data
- Certificate Transparency explained
- CAA record reference
Frequently asked questions
Which CAA record does a CA use for a subdomain?+
Why would a CA that issued my current certificate fail on renewal?+
Does accounturi work with every CA?+
What does issuewild ";" do?+
Is a domain with no CAA record misconfigured?+
How current is the Certificate Transparency data in the checker?+
Tags: #caa, #dns, #tls, #certificate-transparency, #acme