h-push-stream-unpromised
· RFC 9114 §6.2.2 · correctness · layer http3 · udp/4504 · MUST
Passing this means: Rejected something invalid, with the code the RFC names.
Anomaly type: other_uni_stream
How each client answered
| Client | Version | Verdict | What happened |
|---|---|---|---|
| curl | libcurl/8.23.0 ngtcp2/1.25.0 | Fail | Objected at the QUIC layer (rejected at the QUIC layer with INTERNAL_ERROR) instead of signalling the HTTP/3 error. The violation was detected and rejected, which is the right instinct; §8.1 requires an HTTP/3 connection error to be carried in an application close, and this test names 0x108. A transport close carries no HTTP/3 code at all, so a peer has no way to learn what was wrong. |
| quinn | noq fork (189b0ed) | Pass | Rejected with the required error code 0x108. |
| aioquic | 1.3.0 (PyPI wheel) | Fail | Accepted a protocol violation and carried on. The anomaly was on a server-initiated push 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. |
| chromium | build 1248 | Fail | Rejected, but with error 0x101 where the specification requires 0x108. The violation was detected; the code reported is wrong. |
| quic-go | quic-go v0.61.0 (h1:9So2anK4Tp22) | Pass | Rejected with the required error code 0x108. |
| quiche | 0.30.0 (1c8e976) | Fail | Rejected, but with error 0x103 where the specification requires 0x108. The violation was detected; the code reported is wrong. |
| neqo | 0.31.1 (cac2b74) | Pass | Rejected with the required error code 0x108. |
| picoquic | 8162550 | Fail | Accepted a protocol violation and carried on. The anomaly was on a server-initiated push 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. |
| ngtcp2 | 3c23148 | Fail | Rejected, but with error 0x103 where the specification requires 0x108. The violation was detected; the code reported is wrong. |
| lsquic | 4.9.4 (2b30189) | 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. |
| xquic | 2060a44 | Pass | Rejected with the required error code 0x108. |
| msquic | 2.7.0 (7e6525d) | Fail | Accepted a protocol violation and carried on. The anomaly was on a server-initiated push 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. |
| quico | 0.7.0 (npm) | Pass | Rejected with the required error code 0x108. |
What the clause requires
Close the connection with H3_ID_ERROR. §6.2.2 does not require the push to have been promised first — the stream alone is enough: a client "MUST treat receipt of a push stream as a connection error of type H3_ID_ERROR when no MAX_PUSH_ID frame has been sent", and no client under test sends one. Distinct from the PUSH_PROMISE test, which puts the same violation in a frame on the control stream. This one opens the push stream itself, which a client has to recognise by its stream type before any frame inside it is read.
Judged against RFC 9114.
Run this one yourself
Every test is reachable from your own client. Nothing here needs an account.
curl -s https://conformance.pqcrypta.com/catalog.json \
| jq '.tests[] | select(.id == "h-push-stream-unpromised")'