PQ Crypta Logo

lsquic — HTTP/3 Conformance Results

LiteSpeed lsquic + BoringSSL, 4.9.4 (2b30189). How it answers when the server deliberately breaks the protocol.

PQ CRYPTA PLATFORM

🏠 Main

📰 News

👤 Account

⟨ QUANTUM ERROR PORTAL ⟩

Navigate the Error Dimensions

Jump to an anomaly59

Every one of these is a page: what the server emits, the clause it is judged against, and how each client answered. The full list carries the verdict tallies too.

47Pass
5Fail
7Unsupported
90%of 52 conclusive

Stack: LiteSpeed lsquic + BoringSSL · Language: C · Version: 4.9.4 (2b30189) · Measured 2026-10-27

Badge for a README: https://pqcrypta.com/conformance/badge/lsquic.svg lsquic conformance badge

Known causes behind this client's cells

The run reports what the server saw and stops there. Where a separate experiment has since established why a cell landed where it did, it is recorded here rather than folded into the verdict — a cause found afterwards is not something the run observed, and a suite that quietly upgrades one into the other stops being reproducible.

q-flow-control

lsquic refuses any server offering flow-control windows under 4096 bytes, and says nothing when it does.

A separate experiment drove the real lsquic binary against the same endpoint at a range of initial flow-control windows: at this test's window it completed 0 handshakes out of 6, and with the window relaxed it completed 6 of 6. lsquic's source names the threshold: with es_check_tp_sanity on, as it is by default for HTTP/3, a peer whose initial_max_stream_data_bidi_remote or initial_max_data is under 0x1000 fails the handshake -- a policy of lsquic's, since RFC 9000 sets no minimum. Its default LSQUIC_DF_SILENT_CLOSE then sends no CONNECTION_CLOSE, which is why the endpoint sees only a timeout. Since 2026-09-25 the verdict records the refusal itself; this note is the evidence behind the inference.

Measured by pqcrypta-proxy/src/conformance/lsquic_windows.rs; lsquic src/liblsquic/lsquic_enc_sess_ietf.c, 2026-09-19; source read 2026-09-24.

h-trailers

lsquic rejects response trailers every time -- and its demo client occasionally exits before saying so.

Driven through the suite's own driver ten times on 2026-09-25, lsquic 4.9.4 closed the connection with H3_MESSAGE_ERROR (0x10e) on the trailing HEADERS every time, which is the failure this cell reports. In one scored run of four the server saw no close at all: lsquic's http_client calls exit(2) the moment a stream read fails (bin/http_client.c: "could not read"), and now and then the process ends before the library has sent the CONNECTION_CLOSE it was about to. From the server that looks like a client that finished and left, which a run cannot tell apart from success, so this cell can read pass in a run where the demo client won that race. The rejection is lsquic's behaviour; the silent exit is its demo client's.

Measured by h3-conformance --filter h-trailers, 10 runs; lsquic src/bin/http_client.c, 2026-09-25.

By class

Rolled up by what the clause requires rather than into one number. A client that ignores unknown extensions correctly but never emits the right error codes has a specific, nameable problem, and an average is exactly what hides it.

ClassPassing meansPassFailInconclusive
correctness Rejected something invalid, with the code the RFC names. 16 5 0
discretionary The RFC permits either behaviour; the report says which was chosen. 11 0 0
extensibility Ignored something unknown and carried on. 4 0 0
interoperability Correctly decoded something valid but demanding. 8 0 0
resilience Recovered rather than giving up. 8 0 0

Every result

TestClauseVerdictWhat happened
Version Negotiation offering a reserved version alongside v1 RFC 9000 §6 Pass Responded correctly: sent Version Negotiation for 2 datagram(s); the client did not persist with an unsupported version.
Retry packet for source-address validation RFC 9000 §8.1.2 Pass Responded correctly: echoed the Retry token and completed the handshake.
Reserved transport parameter (31·N+27) RFC 9000 §18.1 Pass Ignored the unrecognised element and carried on: completed a handshake carrying a reserved transport parameter.
Unknown frame type in a 1-RTT packet RFC 9000 §12.4 Pass Responded correctly: closed with FRAME_ENCODING_ERROR, which is the code §12.4 requires for a frame of unknown type.
NEW_CONNECTION_ID followed by RETIRE_CONNECTION_ID RFC 9000 §5.1 Pass Recovered: rotated connection IDs and retired 18 of them.
Stateless reset RFC 9000 §10.3 Fail kept sending after the Stateless Reset: 9 more datagram(s) arrived in the following 3 seconds, after a 500ms grace for packets already in flight (0 of those). RFC 9000 §10.3.1 requires a client that recognises the token to enter the draining period and send nothing further, so this connection is wedged against an endpoint that has forgotten it.
Deliberately tight MAX_DATA and MAX_STREAM_DATA RFC 9000 §4 Unsupported does not accept a server whose flow-control windows are this tight. It abandoned the handshake on this port, whose transport parameters grant 512 bytes per stream and 1024 per connection and differ from the other ports in nothing else, while completing exchanges on others in this session. It sent no CONNECTION_CLOSE to say so (this client runs on the endpoint's own host, where nothing is lost), so the refusal is inferred from where it happened.
ACK Frequency extension offered draft-ietf-quic-ack-frequency Pass Handled it: ignored the extension, which the specification permits.
Packets marked ECT(0) RFC 9000 §13.4 Unsupported does not report ECN counts. 6 of its own datagrams reached this endpoint carrying ECT, so the path preserves the codepoint in both directions and this client's stack sets it -- but nothing came back about the markings we sent, and §13.4.1 requires reporting only where the ECN field is accessible to the endpoint.
Path MTU black hole above a threshold RFC 9000 §14, RFC 8899 Pass Recovered: detected the black hole 1 time(s) and settled on a 1293-byte path MTU (0 datagram(s) swallowed).
Server-initiated PATH_CHALLENGE RFC 9000 §8.2 Pass Responded correctly: answered with 1 PATH_RESPONSE.
0-RTT rejected after the client sends early data RFC 9001 §4.6.2 Pass Recovered and completed the follow-up request.
A second path offered mid-connection draft-ietf-quic-multipath Pass Handled it: declined the multipath offer and stayed on one path, which is conformant.
Spontaneous 1-RTT key update RFC 9001 §6.2 Pass Decoded it and completed the request.
Stream limits set to the minimum a request needs RFC 9000 §4.6 Pass Tolerated it and continued. The specification permits this but does not require it; a client that rejected it would also be conformant.
One datagram in twelve dropped once the path is established RFC 9000 §2.2, §13.3 Pass Recovered and completed the follow-up request.
Datagrams arriving from a second server address RFC 9000 §9.6 Pass Tolerated it and continued. The specification permits this but does not require it; a client that rejected it would also be conformant. The client process had already exited 952ms in, before this test's reaction point at 3005ms, so the silence after that is not evidence either way.
Transport parameter carrying a value the specification forbids RFC 9000 §7.4, §18.2 Fail abandoned the handshake without a CONNECTION_CLOSE. It saw the parameter -- that travels in the handshake -- and §7.4 requires treating it as a connection error of type TRANSPORT_PARAMETER_ERROR, which RFC 9000 §10.2 signals in a CONNECTION_CLOSE. None was sent: this client runs on the endpoint's own host, where nothing is lost in transit.
425 (Too Early) in answer to a request sent as early data RFC 8470 §5.2 Pass Tolerated it and continued. The specification permits this but does not require it; a client that rejected it would also be conformant.
Path marking packets CE, not just ECT(0) RFC 9000 §13.4 Unsupported does not report ECN counts, so the congestion signal had nowhere to be seen. 2 datagram(s) were marked CE and the codepoint demonstrably survives this path, so nothing here was lost in transit -- §13.4.1 requires reporting only where the ECN field is accessible to the endpoint, and for this client it is not.
A second key update after the first is acknowledged RFC 9001 §6.1, §6.5 Pass Decoded it and completed the request.
No stream credit at first, then MAX_STREAMS mid-connection RFC 9000 §4.6 Pass Tolerated it and continued. The specification permits this but does not require it; a client that rejected it would also be conformant.
Reserved SETTINGS identifier (0x1f·N+0x21) RFC 9114 §7.2.4.1 Pass Ignored the unrecognised element and completed the follow-up request. The client process had already exited 1052ms in, before this test's reaction point at never observed, so the silence after that is not evidence either way.
Reserved frame type on the response stream RFC 9114 §7.2.8 Pass Ignored the unrecognised element and completed the follow-up request.
Unidirectional stream with a reserved stream type RFC 9114 §6.2.3 Unsupported grants this endpoint 3 unidirectional streams -- the control stream and the two QPACK streams HTTP/3 requires take them all -- and granted no more within 500ms, so a reserved-type stream could not be opened. The violation cannot be delivered to this client; its stream limit rules it out.
SETTINGS containing the same identifier twice RFC 9114 §7.2.4 Pass Tolerated it and continued. The specification permits this but does not require it; a client that rejected it would also be conformant. The client process had already exited 1052ms in, before this test's reaction point at never observed, so the silence after that is not evidence either way.
A DATA frame on the control stream RFC 9114 §7.2.1 Pass Rejected with the required error code 0x105.
Control stream whose first frame is not SETTINGS RFC 9114 §6.2.1 Pass Rejected with the required error code 0x10a.
A second control stream opened by the server RFC 9114 §6.2.1 Unsupported grants this endpoint 3 unidirectional streams -- the control stream and the two QPACK streams HTTP/3 requires take them all -- and granted no more within 500ms, so a second control stream could not be opened. The violation cannot be delivered to this client; its stream limit rules it out.
Field lines referencing dynamic table insertions RFC 9204 §4.3.3, §4.5.2 Pass Decoded it and completed the request.
Huffman-coded field lines with maximal padding RFC 9204 §4.1.2, RFC 7541 §5.2 Pass Decoded it and completed the request.
Field section larger than the client's advertised maximum RFC 9114 §4.2.2 Pass Decoded it and completed the request.
Trailing field section after the body RFC 9114 §4.1 Pass Decoded it and completed the request.
103 Early Hints before the final response RFC 9110 §15.2, RFC 8297 Pass Recovered and completed the follow-up request.
GOAWAY sent mid-connection RFC 9114 §5.2 Pass Recovered and completed the follow-up request. The client process had already exited 1052ms in, before this test's reaction point at never observed, so the silence after that is not evidence either way.
MAX_PUSH_ID sent by the server RFC 9114 §7.2.7 Pass Rejected with the required error code 0x105.
SETTINGS frame on a request stream RFC 9114 §7.2.4 Pass Rejected with the required error code 0x105.
DATA frame before any HEADERS on the response stream RFC 9114 §4.1 Pass Rejected with the required error code 0x105.
CANCEL_PUSH for a push ID that was never promised RFC 9114 §7.2.3 Pass Rejected with the required error code 0x108.
Field section that blocks until the encoder stream catches up RFC 9204 §2.1.2, §2.2.1 Pass Decoded it and completed the request.
Response stream reset mid-body with H3_REQUEST_CANCELLED RFC 9114 §8, §4.1 Pass Tolerated it and continued. The specification permits this but does not require it; a client that rejected it would also be conformant.
PRIORITY_UPDATE sent by the server RFC 9218 §7.2 Pass Rejected with error 0x105. The specification permits this but does not require it; a client that ignored it would also be conformant.
SETTINGS_ENABLE_CONNECT_PROTOCOL with a value outside 0 and 1 RFC 9220 §3, RFC 8441 §3 Pass Tolerated it and continued. The specification permits this but does not require it; a client that rejected it would also be conformant. The client process had already exited 1053ms in, before this test's reaction point at never observed, so the silence after that is not evidence either way.
PUSH_PROMISE for a push the client never allowed RFC 9114 §7.2.5, §4.6 Pass Rejected with the required error code 0x108.
SETTINGS_H3_DATAGRAM with a value that is neither 0 nor 1 RFC 9297 §2.1.1 Fail Accepted a protocol violation and carried on. The anomaly was on the control stream, and this client extended flow-control credit on it -- a receiver extends credit on a stream only once its application has consumed what was already there, so the bytes were read rather than merely delivered. This should have been rejected.
Encoder stream setting a dynamic table capacity above the client's limit RFC 9204 §4.3.1, §6 Pass Rejected with the required error code 0x201.
A second GOAWAY naming a larger identifier than the first RFC 9114 §5.2 Pass Rejected with the required error code 0x108.
Push stream opened for a push nobody allowed RFC 9114 §6.2.2 Unsupported grants this endpoint 3 unidirectional streams -- the control stream and the two QPACK streams HTTP/3 requires take them all -- and granted no more within 500ms, so a push stream could not be opened. The violation cannot be delivered to this client; its stream limit rules it out.
Field line indexing a static table entry that does not exist RFC 9204 §3.1, §4.5.2 Pass Rejected with the required error code 0x200.
Datagrams delivered out of order RFC 9000 §2.2 Pass Recovered and completed the follow-up request.
Encoder instruction naming a static index that does not exist RFC 9204 §3.1, §4.3.2 Pass Rejected with the required error code 0x201.
Server negotiates only the post-quantum hybrid X25519MLKEM768 RFC 8446 §4.1.4, draft-ietf-tls-hybrid-design Pass Decoded it and completed the request.
Server negotiates only classical X25519 against a hybrid offer RFC 8446 §4.1.1, draft-ietf-tls-hybrid-design §5 Pass Tolerated it and continued. The specification permits this but does not require it; a client that rejected it would also be conformant.
Hybrid key share large enough to split the Initial across packets RFC 9000 §8.1, §14.1, RFC 9001 §4.4 Pass Recovered and completed the follow-up request.
Server selects a key exchange group the client never offered RFC 8446 §4.1.3, §4.2.8, RFC 9001 §4.8 Fail abandoned the handshake without any alert. The group was not accepted, but §4.1.3 requires the abort to carry illegal_parameter, and RFC 9001 §4.8 delivers an alert -- a generic one is permitted -- in a CONNECTION_CLOSE. None was sent: this client runs on the endpoint's own host, where nothing is lost in transit.
Hybrid key share with an intact X25519 half and a corrupt ML-KEM half draft-ietf-tls-hybrid-design §3.2, RFC 8446 §4.1.3 Pass Responded correctly: did not complete the handshake (timed out). The shared secret is both halves through the key schedule, so a corrupt ML-KEM half must break it -- and this client did not fall back to the intact X25519 half.
Hybrid key share whose length does not match the group named with it draft-kwiatkowski-tls-ecdhe-mlkem §3.1.2, RFC 8446 §6.2, RFC 9001 §4.8 Fail abandoned the handshake without any alert. §3.1.2 requires the abort to carry illegal_parameter, and RFC 9001 §4.8 delivers an alert -- a generic one is permitted -- in a CONNECTION_CLOSE. None was sent: this client runs on the endpoint's own host, where nothing is lost in transit.
Post-quantum certificate chain, compressed per RFC 8879 RFC 8879 §4, RFC 8446 §4.4.2 Unsupported The client was refused before a handshake existed (detected an error with protocol compliance that was not covered by more specific error codes: authentication failed). The refusal is itself the measurement on this tier, but what the client lacked is not recorded in it: this endpoint constrains both the key exchange group and the certificate's signature algorithm, and the error names neither.
GREASE named group a client must tolerate RFC 8701 §4, RFC 8446 §4.2.7 Pass Ignored the unrecognised element and completed the follow-up request.