Debugging WebTransport handshake errors: a practical checklist
Why a WebTransport connection fails and what to check: certificates, serverCertificateHashes, HTTP/3 support, UDP, origin and path, per the spec.
WebTransport Day
Published
Last updated:
Facts checked:
4 min read
- Updated Oct 28, 2026
- ✓ Facts checked Oct 28, 2026
- Sources: W3C, IETF, MDN
Key facts (checked October 28, 2026)
- Usual causes
- Certificate, HTTP/3 or WebTransport support, path or origin, UDP reachability
- Self-signed certificates
- Need serverCertificateHashes: ECDSA P-256 key, validity under two weeks
- Error detail
- Intentionally limited by browsers until the endpoint is verified as WebTransport
Why does a WebTransport connection fail?
A WebTransport session needs several things to line up before the first byte of your data moves: a reachable UDP port, a QUIC connection, a trusted certificate, an HTTP/3 server that supports WebTransport, a path it serves, and an Origin it accepts. If any one is wrong, the browser rejects the ready promise, and usually closed as well, with little explanation.
Text version
| Hop | Fails when | What to check |
|---|---|---|
| 1. DNS | The name does not resolve. | Check the hostname in a resolver. |
| 2. UDP reachable | UDP is blocked, or nothing listens on that port. | Test from another network; check firewall and security groups. |
| 3. QUIC and TLS | The certificate is untrusted, expired or for another name. | Use a trusted certificate, or serverCertificateHashes for a short-lived ECDSA P-256 one. |
| 4. HTTP/3 SETTINGS | The server lacks HTTP/3 or WebTransport support, or does not enable it. | Confirm HTTP/3 and WebTransport are on in the server. |
| 5. Extended CONNECT | The path or the Origin is rejected (403 or 405). | Check the URL path and the origin policy. |
| 6. Session ready | No failure here: the ready promise resolves. | Send a message on a stream or as a datagram. |
What does the browser tell you?
Two things are worth knowing before you start:
- Synchronous errors. The
WebTransportconstructor throwsSyntaxErrorfor an invalid URL, a non-httpsscheme or a fragment in the URL, according to the specification and MDN. Check this before suspecting the network. - Asynchronous failures. On a network or establishment failure the specification moves the transport to a failed state and rejects
closedandreadywith aWebTransportError(itssourceissession). The specification also says the detailed reason is withheld until the endpoint has been verified as a WebTransport server, and certificate errors are fatal. So the message you see is intentionally unspecific. Message strings are not specified, so do not parse them. For reference, when we pointed the tester at a closed port in a Chromium-based browser on 2026-10-28, it reportedWebTransportError: Opening handshake failed.with sourcesession; other browsers and versions may word it differently.
When a connection that was working ends gracefully, closed resolves with a close code and reason instead.
What should I check first?
Work through these in order. Each item is a real constraint from the specification, the IETF draft or the QUIC and HTTP/3 RFCs.
- The URL. Use
https://host:port/path. WebTransport has no plain-text mode. - UDP reachability. WebTransport over HTTP/3 uses QUIC, which runs over UDP. If a firewall, security group or network filters UDP to that port, the session cannot establish. Browsers do not document this as a distinct error, so treat it as a practical cause to rule out, not something the error will state.
- HTTP/3 and WebTransport enabled on the server. The draft requires the server to signal extended CONNECT support, HTTP Datagrams and the WebTransport setting, and to allow QUIC datagrams. If it does not, clients must not start a session. A server that only speaks HTTP/1.1 or HTTP/2 over TCP will not work.
- The path. The server must accept WebTransport on the exact path in your URL. The draft suggests a 405 for an unsupported resource, and clients do not follow redirects for this request.
- The origin. Browsers send an
Originheader. A server may reject origins it does not trust (the draft suggests 403). Testing from a different origin than your app can hide or reveal this. - The certificate. See the next section.
- A proxy or CDN in between. Several CDNs and load balancers terminate HTTP/3 at the edge or speak HTTP/1.1 to the origin. See WebTransport and serverless.
How do certificates work with WebTransport?
A normal connection uses the Web PKI. The server’s certificate must be valid for the hostname and chain to a trusted authority, as with any HTTPS site.
For development you can instead supply serverCertificateHashes. According to the specification and MDN:
- The option takes an array of objects with
algorithm: 'sha-256'and avalueholding the hash. - The hash is the SHA-256 of the DER-encoded leaf certificate.
- The certificate must be X.509v3 and currently valid, and its total validity must not exceed two weeks.
- The key algorithms an implementation accepts are implementation-defined but must include ECDSA P-256 and must not include RSA.
- Several hashes can be supplied, which allows rotation.
- When hashes are used, they replace normal certificate validation for that connection, and the connection cannot be pooled.
Generate a compliant certificate and its hash with OpenSSL (an example, adjust names to suit):
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes \
-days 13 -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost" \
-keyout key.pem -out cert.pem
openssl x509 -in cert.pem -outform der | openssl dgst -sha256
Paste the resulting hex into the optional field in the WebTransport tester. A 14-day certificate sits exactly at the limit, so we use 13 days to stay under it.
How do I tell a server problem from a client problem?
Isolate it:
- Point the tester at a server you do not control that is documented as an echo server (see the echo server list). If it connects, your browser and network are fine.
- Run your own server locally with a library example (local testing guide) and connect with
serverCertificateHashes. If that works, the problem is hosting, DNS, certificates or the network path. - Check the browser’s developer tools network or QUIC logging for the failing connection, and the server’s own logs for the request and its response status.
- Test from a different network. If UDP is filtered on one network, it fails there only.
What about older servers and draft versions?
The IETF protocol document has been revised many times. Library READMEs say which draft they implement (for example webtransport-go states draft-16), and some older examples target earlier drafts. A mismatch can look like any other handshake failure. See client and server libraries.
Still stuck?
Reduce the problem to the smallest case: one server, one URL, one browser, one echo message. The tester prints the connection state and any error the browser provides, which is the information to include when you ask for help.
Frequently asked questions
Why is the error message so vague?
The specification withholds the specific connection error until the endpoint is verified to be a WebTransport server, which prevents pages from using failed connections to probe networks. Expect an opaque failure: the transport's closed and ready promises reject.
How do I use a self-signed certificate with WebTransport?
Pass serverCertificateHashes when constructing WebTransport. The certificate must be X.509v3 with a validity period of at most two weeks, use an ECDSA P-256 key (RSA keys must not be accepted), and you supply the SHA-256 hash of its DER encoding.
Does a 403 or 405 from the server show up in the browser?
The draft recommends 403 for a rejected Origin and 405 for an unsupported resource, but the browser reports the failure through the transport promises rather than as an HTTP status you can read.
Sources
Facts on this page were last checked against these sources on October 28, 2026.
Cite this page
- Title
- Debugging WebTransport handshake errors: a practical checklist
- Author
- WebTransport Day (organization)
- URL
- https://webtransport.day/guides/debug-webtransport-handshake-errors/
- Updated
WebTransport Day. "Debugging WebTransport handshake errors: a practical checklist." Last updated October 28, 2026. https://webtransport.day/guides/debug-webtransport-handshake-errors/
Related reading
How to test WebTransport locally with an example server
Run a local WebTransport server from the wtransport or webtransport-go examples, then connect from the browser, with a self-signed certificate hash.
Updated
What is WebTransport? Streams, datagrams, HTTP/3 and QUIC explained
WebTransport explained: one multiplexed HTTP/3 connection with reliable streams and unreliable datagrams. How it works, support and standards status.
Updated
WebTransport client and server libraries: what exists and its status
Verified WebTransport libraries for Rust, Go, Python, Node.js, .NET and Deno, with licence, latest release and the status caveats each project states.
Updated