The safety net just became optional
The certificate passed every check you ran. Chrome was green, the staging smoke test was green, curl on your laptop was green. Then a Go service consuming your API started throwing x509: certificate signed by unknown authority, from one client, intermittently, and you burned an afternoon convinced it was DNS. It wasn't. You shipped a chain with a hole in it, and Chrome quietly patched the hole every time you looked. The Go client didn't, because nobody handed it the missing piece and it never went looking.
That missing piece gets fetched through a certificate field called AIA, and on September 3, 2026 the CA/Browser Forum finished voting on a ballot that makes the whole field optional. Ballot SC104 changes the presence of the Authority Information Access extension in subscriber certificates from MUST to SHOULD. It passed unanimously: 21 to 0 among Certificate Issuers, 5 to 0 among the browsers (Apple, Cisco, Google, Microsoft, Mozilla). It's sitting in the mandatory IPR review period until October 3, and then it's part of the Baseline Requirements.
The reason this matters has nothing to do with the vote count. It's that a crutch a lot of production TLS quietly leans on is now something your CA is allowed to take away, and most people don't know they're leaning on it.
What AIA actually carried
The AIA extension holds URLs, and historically it held two kinds. The first is id-ad-caIssuers: a link to the issuing intermediate certificate, so a client that receives a leaf with no intermediate attached can go download the missing link itself. The second is id-ad-ocsp: the address of the CA's OCSP responder, where a client could ask "is this certificate revoked?"
Both of those have been quietly dying for years. OCSP is the more advanced corpse. The Forum already made the OCSP URL a MAY rather than a requirement, Let's Encrypt shut its OCSP responders down in 2025, and browsers moved revocation to pushed lists: CRLite in Firefox, CRLSets in Chrome. We went through that whole shift in how CRLite changed revocation checking. So id-ad-ocsp was already pointless in a modern certificate.
That left the caIssuers URL as the only thing keeping the AIA extension alive, and caIssuers was itself already a SHOULD, not a MUST. So you had a mandatory container wrapping two things that were both optional. SC104 just resolved the contradiction the obvious way: if everything inside can be absent, stop pretending the box has to be there. Ethan Davis at Google Trust Services proposed it, DigiCert and SwissSign endorsed it, and nobody argued.
Why this is not a paperwork change
The tidy reading is that SC104 aligns some MUSTs and SHOULDs and changes nothing on the wire. That's true for the certificates that already ship a full chain. It is not true for the large population of servers that don't, and get away with it purely because a browser bails them out.
Here's the mechanism people forget. When a client gets a leaf certificate but no intermediate, it can't build a path to a trusted root. The middle link is missing. Some clients respond by reading the caIssuers URL out of the AIA extension, downloading the intermediate over plain HTTP, and completing the chain on the fly. That's AIA fetching, sometimes called AIA chasing. It papers over an incomplete server config so thoroughly that the operator never learns the config is broken.
Once caIssuers is genuinely optional, a CA can issue you a leaf with no AIA extension at all. No URL to chase. And on that day, the fetch that was silently rescuing your incomplete chain returns nothing, and the clients doing the fetching join the clients that never did.
Who covers for you, and who was never going to
The uncomfortable part is how uneven AIA fetching already is. It is not a web standard everyone implements. It's a per-client choice, and the split is wide.
Chrome does it on desktop. Safari does it. Chrome on Android does not. Firefox has refused to implement AIA fetching for over fifteen years on the explicit grounds that it rewards broken server configuration; instead it preloads intermediates it has seen disclosed to the CA transparency ecosystem and caches ones it encounters. That works right up until you're the freshly issued cert from an intermediate Firefox hasn't preloaded yet.
Then there's everything that isn't a browser, which is where your infrastructure actually lives:
- OpenSSL, including
openssl s_clientandopenssl verify, does not fetch. What the server sends is what it checks. - Go's
crypto/tlsdoes not fetch. This is why the Go service in the opening broke. - Java's default PKIX validator does not fetch unless you set
com.sun.security.enableAIAcaIssuers=true, and that property is off by default. - Node, Python's
requests, and most language HTTP stacks that sit on OpenSSL inherit its behaviour: no fetch.
So the set of clients that quietly fixed your chain was always "some browsers." Every API consumer, every service mesh sidecar, every webhook receiver, every mobile app using a non-system TLS stack, every curl in a deploy script was already on its own. SC104 doesn't create this problem. It removes the last excuse for not having fixed it, by letting the URL those few browsers relied on disappear.
Find out if you're exposed in two commands
You don't have to guess whether you depend on the safety net. Ask your own endpoint what it presents.
echo | openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null \
| grep -E '^\s*[0-9]+ s:'
You want to see more than one line. A single 0 s: with your leaf and nothing below it means you're shipping the leaf alone and living entirely on AIA fetching and client-side caches. A healthy public chain shows the leaf and at least one intermediate:
0 s:CN=example.com
1 s:C=US, O=Let's Encrypt, CN=E7
The root doesn't need to be there. Clients have it in their trust store already, and sending it just wastes handshake bytes.
Separately, check whether the certificate even carries an AIA extension today, because that's the field about to go optional:
openssl x509 -in leaf.pem -noout -text | grep -A4 "Authority Information Access"
If that prints a CA Issuers - URI line, that URL is the crutch. If it prints nothing, your CA has already dropped AIA and you had better be sending the full chain yourself, because nothing is coming to save you.
Ship the whole chain and stop hoping
The fix is old advice that SC104 turns from "good hygiene" into "the only thing holding your TLS up." Serve the leaf plus every intermediate up to, but not including, the root. Every mainstream tool wants the leaf first, then intermediates in order.
On nginx, the ssl_certificate file must be the concatenation, not just the leaf:
cat leaf.pem intermediate.pem > fullchain.pem
server {
listen 443 ssl;
ssl_certificate /etc/ssl/example/fullchain.pem;
ssl_certificate_key /etc/ssl/example/privkey.pem;
}
If you run Certbot, fullchain.pem already contains leaf plus intermediate, so point nginx at that file and not at cert.pem, which is the leaf alone and is the single most common way this breaks. Caddy assembles and serves the full chain on its own; there's nothing to configure. cert-manager writes the assembled chain into the tls.crt key of the Secret, so as long as your Ingress reads that Secret you're fine, but confirm it after an issuer change rather than assuming.
Whatever you run, verify with the trust store of a client that never fetches, not with a browser:
curl -vI https://example.com 2>&1 | grep -i "SSL certificate verify"
curl uses OpenSSL's view of the world. If curl is happy, the Go services and the Java clients and the mobile apps will be too. If curl complains and Chrome doesn't, you've just watched the exact gap SC104 widens.
This is the same story as the incomplete-chain bug
If shipping the full chain sounds familiar, it's because incomplete chains have been silently breaking non-browser clients for years, and we wrote the whole debugging playbook in why your SSL works in Chrome but breaks everywhere else. What's new isn't the failure mode. It's that the failure mode used to require you to also misconfigure your server. Now the CA is permitted to remove the fallback URL on its own schedule, and the first you'll hear of it is a monitoring alert or a support ticket from whoever runs a Go client against you.
Which is the real operational takeaway: expiry monitoring was never enough, and it's about to be less enough. A certificate can be valid, unexpired, and completely unroutable for half your clients because the chain is short a link and there's no URL to chase. If your monitoring only watches notAfter, it will report green through the entire incident. Watch chain completeness from a client that doesn't fetch, on the same schedule you watch expiry, and you'll catch the hole before your users do.
Frequently asked questions
Does SC104 mean my existing certificates will suddenly stop working? No. SC104 permits CAs to omit the AIA extension in the future; it doesn't retroactively change certificates already issued, and it doesn't force any CA to drop AIA at all. The risk is forward-looking: as CAs start exercising the option, any endpoint that was surviving on AIA fetching loses that fallback the next time it's issued a certificate without the extension.
If Chrome fetches the missing intermediate anyway, why should I care? Because Chrome fetching is not the same as your clients working. Chrome on Android, Firefox, OpenSSL, Go, Java, curl, and most non-browser HTTP stacks either don't fetch or don't fetch reliably, and those are the clients hitting your APIs and webhooks. Passing in a desktop browser tells you almost nothing about whether an incomplete chain will hold in production.
How do I know if my CA still includes an AIA extension?
Run openssl x509 -in leaf.pem -noout -text and look for an "Authority Information Access" block. A CA Issuers URI means the fallback is still present; its absence means you're already relying entirely on the chain you serve yourself. Check after any issuer or profile change, since that's when it's most likely to shift.
Does this affect revocation checking too? Indirectly. The AIA extension also carried the OCSP responder URL, but OCSP was already made optional and the major browsers moved to pushed revocation lists like CRLite and CRLSets. Dropping AIA removes a URL that was mostly vestigial for revocation; the practical revocation story doesn't change because it had already moved off OCSP.
What's the single thing to do about it now?
Serve the full chain, leaf plus intermediates, from every endpoint, and verify it with a client that doesn't do AIA fetching, such as openssl s_client -showcerts or curl, rather than trusting a green padlock in a desktop browser.