Skip to main content

Overview

When your script calls fetch() 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:
Wrap the call in 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.
You do not need to configure anything for these.
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 to Deno.createHttpClient:
The certificate you supply is added to the trust store for that client only. Hostname and expiry checks still apply: this adds a trust anchor, it does not disable verification.

Client Certificates (mTLS)

Some origins require the client to present its own certificate. Pass the PEM-encoded certificate and private key to Deno.createHttpClient and use that client for the fetch. Store both as environment secrets so they never appear in your source code:
The origin’s own certificate is still verified as usual.
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 affects fetch() calls to other URLs.

Troubleshooting

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.
The certificate is valid, but not for the hostname you connected to. bunny.net’s own edge certificates are accepted automatically.
The origin’s certificate has expired. Renew it on the origin. Expiry cannot be bypassed for external origins.
An HTTPS origin reached by IP address received no matching server name.
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.
Turn off Verify Origin SSL on the Pull Zone. This applies only to your configured origin.

References

Last modified on August 18, 2026