What Is a CAA Record
Learn how CAA records control which Certificate Authorities can issue SSL/TLS certificates for your domain. Includes examples for the DNScale dashboard and API.
What you'll learn
- Configure CAA records to restrict SSL/TLS certificate issuance to authorized Certificate Authorities only
- Use issuewild, issue, and iodef tags correctly to control regular, wildcard, and violation reporting policies
- Set up CAA records for Let's Encrypt, DigiCert, and other popular CAs with proper inheritance rules
- Troubleshoot certificate issuance failures caused by CAA misconfiguration and understand DNSSEC interaction
A CAA (Certification Authority Authorization) record specifies which Certificate Authorities (CAs) are permitted to issue SSL/TLS certificates for your domain. CAA records are a DNS-based security measure that helps prevent unauthorized certificate issuance ā one of the most important protections you can add to your DNS zone.
Since September 2017 (mandated by the CA/Browser Forum Ballot 187), all CAs are required to check CAA records before issuing a certificate. This makes CAA records one of the few DNS-based controls that is universally enforced by the certificate industry.
How CAA Records Work
When a CA receives a certificate request, it must check for CAA records:
example.com. 3600 CAA 0 issue "letsencrypt.org"This tells CAs: "Only Let's Encrypt may issue certificates for example.com."
If no CAA records exist, any CA can issue certificates. Once you add CAA records, only authorized CAs can issue. This is an opt-in security mechanism ā the default behavior (no CAA records) is permissive.
The CA performs this check by querying your domain's authoritative nameservers for CAA records. If the DNS response is SERVFAIL (server failure) rather than NOERROR or NXDOMAIN, the CA must refuse to issue. This is a safety measure ā it prevents a CA from issuing a certificate when it can't verify the CAA policy, which could happen during a DNS attack.
Record Components
| Component | Description | Values |
|---|---|---|
| Flag | Critical flag | 0 (non-critical) or 128 (critical) |
| Tag | Property type | issue, issuewild, iodef |
| Value | CA domain or contact | "letsencrypt.org" |
Tags Explained in Depth
The issue Tag
The issue tag authorizes a CA to issue regular (non-wildcard) certificates for the domain:
example.com. 3600 CAA 0 issue "letsencrypt.org"You can include parameters after the CA identifier to restrict issuance further. For example, some CAs support an accounturi parameter to restrict issuance to a specific ACME account:
example.com. 3600 CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456"This ensures that only your specific Let's Encrypt account can obtain certificates, preventing even authorized accounts under different ownership from issuing for your domain.
The issuewild Tag
The issuewild tag specifically controls wildcard certificate issuance (*.example.com). This is separate from issue because wildcard certificates carry greater risk ā a wildcard certificate is valid for any subdomain.
; Allow Let's Encrypt for regular certs
example.com. 3600 CAA 0 issue "letsencrypt.org"
; Only allow DigiCert for wildcard certs
example.com. 3600 CAA 0 issuewild "digicert.com"If you have issue records but no issuewild records, the issue records also control wildcard issuance. If you add any issuewild record, it takes over wildcard control exclusively.
To deny all wildcard certificates while allowing regular ones:
example.com. 3600 CAA 0 issue "letsencrypt.org"
example.com. 3600 CAA 0 issuewild ";"The iodef Tag
The iodef (Incident Object Description Exchange Format) tag specifies where violation reports should be sent when a CA encounters a policy violation:
example.com. 3600 CAA 0 iodef "mailto:security@example.com"
example.com. 3600 CAA 0 iodef "https://example.com/caa-report"Reports can be sent via email (mailto:) or HTTP POST (https://). Not all CAs send reports, but having the iodef record ensures you're notified by CAs that do support it.
Add
iodefrecords first, before restricting issuance withissuerecords. This way, if someone attempts to get a certificate from an unauthorized CA, you'll be notified of the attempt. This is a good monitoring-first approach to deploying CAA.
The Flag Field
The flag field is either 0 or 128:
- Flag
0(non-critical) -- the CA should obey the record but can still issue if it doesn't understand the tag - Flag
128(critical) -- the CA must not issue if it doesn't understand the tag type
Use flag 128 only for tags that are essential to your security policy. For standard issue, issuewild, and iodef tags, flag 0 is appropriate since all modern CAs understand these tags.
Common Use Cases
Allow Single CA (Let's Encrypt)
example.com. 3600 CAA 0 issue "letsencrypt.org"This is the most common setup for sites using Let's Encrypt with automated certificate management via ACME (Automated Certificate Management Environment). The DNS-01 challenge for Let's Encrypt domain validation works seamlessly alongside CAA records.
Allow Multiple CAs
example.com. 3600 CAA 0 issue "letsencrypt.org"
example.com. 3600 CAA 0 issue "digicert.com"
example.com. 3600 CAA 0 issue "sectigo.com"Separate Regular and Wildcard Issuance
; Regular certs from Let's Encrypt
example.com. 3600 CAA 0 issue "letsencrypt.org"
; Wildcard certs from DigiCert only
example.com. 3600 CAA 0 issuewild "digicert.com"Deny All Certificate Issuance
example.com. 3600 CAA 0 issue ";"This prevents any CA from issuing certificates for the domain. Useful for domains that should never have HTTPS, such as internal-only names or parked domains.
Complete Production Setup
; Allow Let's Encrypt for regular and wildcard certs
example.com. 3600 CAA 0 issue "letsencrypt.org"
example.com. 3600 CAA 0 issuewild "letsencrypt.org"
; Receive violation reports
example.com. 3600 CAA 0 iodef "mailto:security@example.com"
example.com. 3600 CAA 0 iodef "https://example.com/caa-report"With Violation Reporting
example.com. 3600 CAA 0 issue "letsencrypt.org"
example.com. 3600 CAA 0 iodef "mailto:security@example.com"
example.com. 3600 CAA 0 iodef "https://example.com/caa-report"Popular CA Identifiers
| CA | CAA Value |
|---|---|
| Let's Encrypt | letsencrypt.org |
| DigiCert | digicert.com |
| Sectigo (Comodo) | sectigo.com |
| GlobalSign | globalsign.com |
| GoDaddy | godaddy.com |
| Amazon (ACM) | amazon.com |
| Google Trust Services | pki.goog |
| Cloudflare | digicert.com (Cloudflare uses DigiCert) |
| ZeroSSL | sectigo.com |
| Buypass | buypass.com |
| SSL.com | ssl.com |
Always verify the exact CAA identifier with your CA. Some CAs use their parent company's domain, and the identifier may not match the CA's marketing name.
Record Format
| Field | Description | Example |
|---|---|---|
| Name | Domain (usually apex) | @ or subdomain |
| Type | Record type | CAA |
| Flag | Critical flag | 0 or 128 |
| Tag | Property type | issue, issuewild, iodef |
| Value | CA identifier | letsencrypt.org |
| TTL | Time to live (seconds) | 3600 |
Adding a CAA Record
Using the Dashboard
- Navigate to your zone in the DNScale dashboard
- Click Add Record
- Configure the record:
- Name: Usually
@for apex domain - Type: Select
CAA - Flag: Choose
0(Non-critical) or128(Critical) - Tag: Select
issue,issuewild, oriodef - Value: Enter the CA domain or contact address
- TTL: Set the cache duration (default: 3600)
- Name: Usually
- Click Create Record
Using the API
Allow Let's Encrypt to issue certificates:
curl -X POST "https://api.dnscale.eu/v1/zones/{zone_id}/records" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "@",
"type": "CAA",
"content": "0 issue \"letsencrypt.org\"",
"ttl": 3600
}'Add wildcard authorization:
curl -X POST "https://api.dnscale.eu/v1/zones/{zone_id}/records" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "@",
"type": "CAA",
"content": "0 issuewild \"letsencrypt.org\"",
"ttl": 3600
}'Add violation reporting:
curl -X POST "https://api.dnscale.eu/v1/zones/{zone_id}/records" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "@",
"type": "CAA",
"content": "0 iodef \"mailto:security@example.com\"",
"ttl": 3600
}'API Response:
{
"status": "success",
"data": {
"message": "Record created successfully",
"record": {
"id": "encoded-record-id",
"name": "example.com.",
"type": "CAA",
"content": "0 issue \"letsencrypt.org\"",
"ttl": 3600,
"disabled": false
}
}
}CAA Inheritance
CAA records are inherited by subdomains unless overridden:
; Apex CAA - applies to example.com and all subdomains
example.com. 3600 CAA 0 issue "letsencrypt.org"
; Override for specific subdomain
shop.example.com. 3600 CAA 0 issue "digicert.com"In this case:
example.com-- Let's Encrypt onlywww.example.com-- Let's Encrypt only (inherited)shop.example.com-- DigiCert only (overridden)api.shop.example.com-- DigiCert only (inherited from shop.example.com)
The CA walks up the DNS tree from the requested domain name until it finds CAA records. If it finds them at any level, those records apply. If it reaches the zone apex without finding any, there are no restrictions.
CAA and DNSSEC Interaction
CAA records work best when combined with DNSSEC. Without DNSSEC, an attacker who can manipulate DNS responses (via cache poisoning or man-in-the-middle) could:
- Remove CAA records to allow any CA to issue certificates
- Add fake CAA records to prevent legitimate certificate issuance (denial of service)
With DNSSEC enabled, the DNS responses are cryptographically signed, ensuring that the CAA records the CA sees are authentic. This makes CAA a much stronger security control.
# Verify DNSSEC is working for your CAA records
dig CAA example.com +dnssec
# Look for the RRSIG record in the response ā this confirms the answer is signedIf your domain uses DNSSEC and the DNSSEC validation fails (SERVFAIL), the CA will refuse to issue a certificate. This is the correct behavior ā it's safer to deny issuance than to issue based on potentially forged DNS responses.
Let's Encrypt and CAA: A Complete Setup
Let's Encrypt is the most popular free CA and works well with CAA records. Here's a complete setup:
; Allow Let's Encrypt for both regular and wildcard certificates
example.com. 3600 CAA 0 issue "letsencrypt.org"
example.com. 3600 CAA 0 issuewild "letsencrypt.org"
; Report violations
example.com. 3600 CAA 0 iodef "mailto:security@example.com"For wildcard certificates with Let's Encrypt, you must use the DNS-01 challenge (creating a TXT record at _acme-challenge.example.com). The DNScale API makes this easy to automate with tools like Terraform, certbot, or acme.sh.
# Example: Let's Encrypt DNS-01 challenge with certbot and DNScale API
certbot certonly --manual --preferred-challenges dns \
-d "*.example.com" -d "example.com"Best Practices
-
Start with monitoring -- Add
iodefrecords to receive reports before restricting issuance -
Include your actual CA -- Before adding restrictive records, verify which CA you currently use
-
Plan for wildcards -- Remember
issuewildis separate fromissue; if you only setissue, it covers both, but once you add anyissuewild, it takes over -
Use non-critical flag (0) -- Only use flag 128 if you want strict enforcement of custom tag types
-
Update before changing CAs -- Add new CA authorization before switching providers; remove old authorization after migration is complete
-
Don't forget subdomains -- Check if subdomains need different policies
-
Enable DNSSEC -- CAA without DNSSEC can be bypassed via DNS manipulation
-
Keep TTL moderate -- Use 3600 seconds (1 hour); too-short TTLs increase lookup overhead during certificate issuance
-
Document your policy -- Record which CAs are authorized and why, for your team's reference
Troubleshooting Certificate Issuance
If certificate issuance fails after adding CAA records:
-
Verify CAA records exist:
dig CAA example.com dig CAA example.com @ns1.dnscale.eu -
Check for correct CA identifier:
- Contact your CA for the exact identifier
- Some CAs use parent company identifiers (e.g., Cloudflare uses
digicert.com) - The identifier is case-insensitive
-
Verify wildcard authorization:
issuewildis required for wildcard certificates- If only
issueexists and noissuewild, theissuepolicy applies to wildcards too - If any
issuewildrecord exists, it exclusively controls wildcard issuance
-
Check subdomain inheritance:
- Subdomains inherit parent CAA unless overridden
- Check for overriding CAA records at intermediate domain levels
-
Check for DNSSEC issues:
dig CAA example.com +dnssec # If SERVFAIL, your DNSSEC may be broken ā CAs will refuse to issue -
Wait for propagation:
- Newly added CAA records may not be visible to all DNS resolvers yet
- Allow time for TTL-based caching to expire
Testing CAA Records
# Query CAA records
dig CAA example.com
# Check with specific nameserver
dig CAA example.com @ns1.dnscale.eu
# Short output
dig CAA example.com +short
# Check what a subdomain inherits
dig CAA www.example.com
dig CAA shop.example.com
# Verify alongside TLSA records for complete certificate security
dig TLSA _443._tcp.example.comRelated Record Types
- TXT -- Domain verification for CAs and email security
- TLSA -- DANE certificate pinning in DNS
- A -- Server address for domain validation
- AAAA -- IPv6 server address
- NS -- Nameserver delegation
- SSL/TLS Certificates -- Certificate fundamentals
- SSL Certificate Chain -- How certificate chains work
- DNS Record Types -- Overview of all DNS record types
- DNSSEC Key Management -- Securing CAA records with DNSSEC
Conclusion
CAA records are a simple but effective security measure for controlling SSL/TLS certificate issuance. By specifying which CAs can issue certificates for your domain, you reduce the risk of unauthorized certificate creation. When combined with DNSSEC, CAA records become a strong defense against certificate-based attacks. Use iodef for visibility, issue and issuewild for control, and always test your CAA configuration before relying on automated certificate renewal. DNScale makes it easy to configure CAA records with intuitive tag selection for issue, issuewild, and iodef policies.
Ready to manage your DNS with confidence?
DNScale provides anycast DNS hosting with a global network, real-time analytics, and an easy-to-use API.
Start free