Overview
When your script callsfetch() on an https:// URL, or when the runtime
fetches your Pull Zone origin, it opens a fully verified TLS connection from the
bunny.net edge to that host. It performs the same checks a browser does: the
certificate must chain to a trusted public Certificate Authority, be valid for
the hostname you connected to, and not be expired.
Most of the time this needs no thought.
Fetching an external HTTPS URL works out of the box:
try/catch so that a certificate problem on the origin
becomes a response you control instead of an unhandled error:
If a
fetch() fails on the certificate, it rejects with a TypeError whose message names the problem, for example invalid peer certificate: UnknownIssuer. The troubleshooting section is organized by that message.Handled Automatically
Some origins are misconfigured in ways that every browser tolerates. The runtime handles these for you so that a fetch behaves the way it does in a browser. None of them weaken verification: the certificate chain is still checked against trusted roots on every connection, and a certificate that fails for a real reason (untrusted issuer, expired, wrong hostname) still fails.- Missing intermediate certificates. Many servers send only their own leaf certificate and omit the intermediate that links it to the root CA. When a certificate fails only for this reason, the runtime completes the chain from a built-in list of publicly disclosed intermediates, sourced from the Common CA Database (CCADB), then verifies the completed chain against the trusted roots.
- bunny.net edge hostnames without their own certificate. A hostname pointed at
the bunny.net edge that has no SSL provisioned for that specific name (a
white-label or alias domain, often reached after a redirect) is answered with
one of bunny.net’s own edge certificates, such as
*.b-cdn.net. When verification fails only on the hostname check and the certificate provably belongs to bunny.net, the connection is accepted. A mismatched third-party certificate is never accepted this way. - Older TLS 1.2 origins. Legacy handshakes that some strict clients reject (for example an ECDSA P-256 certificate whose handshake is signed with SHA-384) connect normally.
These conveniences apply to
fetch() and origin connections only. The lower-level node:tls module performs standard, stricter verification and rejects both cases.Private Certificate Authorities
The built-in intermediate list only covers certificates disclosed in the CCADB. If your origin uses a private or internal Certificate Authority, trust its certificate for that fetch by passing it toDeno.createHttpClient:
Client Certificates (mTLS)
Some origins require the client to present its own certificate. Pass the PEM-encoded certificate and private key toDeno.createHttpClient and use that client for the fetch. Store both as environment secrets so they never appear in your source code:
If you have trouble storing a multi-line PEM value in a secret, store it base64-encoded instead and decode it in the script with
atob(process.env.ClientCert).Your Pull Zone Origin
Your pullzone origin fetch has their own configuration in the Pullzone. Those do not affectsfetch() calls to other URLs.
Troubleshooting
UnknownIssuer
UnknownIssuer
The origin’s certificate does not chain to a public Certificate Authority. The usual cause is a private or internal CA, or an intermediate that is not disclosed in the CCADB. Trust the CA with
Deno.createHttpClient({ caCerts }). Public origins that merely omit a disclosed intermediate already work automatically.NotValidForName
NotValidForName
The certificate is valid, but not for the hostname you connected to. bunny.net’s own edge certificates are accepted automatically.
Expired
Expired
The origin’s certificate has expired. Renew it on the origin. Expiry cannot be bypassed for external origins.
421 Misdirected Request
421 Misdirected Request
An HTTPS origin reached by IP address received no matching server name.
Works in a browser but fails in a script
Works in a browser but fails in a script
Browsers hide certificate-chain and hostname problems that a strict client will not. Check the origin’s certificate with
openssl:unable to verify the first certificate means a missing intermediate: fix the origin to send its full chain, or use caCerts if the CA is private. Verify return code: 0 (ok) means the chain is fine and the problem lies elsewhere.Your own origin uses a self-signed certificate
Your own origin uses a self-signed certificate
Turn off Verify Origin SSL on the Pull Zone. This applies only to your configured origin.