h-push-promise-unsolicited
· RFC 9114 §7.2.5, §4.6 · correctness · layer http3 · udp/4500 · MUST
Passing this means: Rejected something invalid, with the code the RFC names.
Anomaly type: response_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 in the response the client read and delivered, so it was seen; this should have been rejected. |
| chromium | build 1248 | Fail | Rejected, but with error 0x106 where the specification requires 0x108. The violation was detected; the code reported is wrong. |
| quic-go | quic-go v0.61.0 (h1:9So2anK4Tp22) | Fail | Accepted a protocol violation and carried on. The anomaly was in the response the client read and delivered, so it was seen; this should have been rejected. |
| quiche | 0.30.0 (1c8e976) | Fail | Accepted a protocol violation and carried on. The anomaly was in the response the client read and delivered, so it was seen; this should have been rejected. |
| 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 in the response the client read and delivered, so it was seen; this should have been rejected. |
| ngtcp2 | 3c23148 | Fail | Rejected, but with error 0x105 where the specification requires 0x108. The violation was detected; the code reported is wrong. |
| lsquic | 4.9.4 (2b30189) | Pass | Rejected with the required error code 0x108. |
| xquic | 2060a44 | Fail | Accepted a protocol violation and carried on. The anomaly was in the response the client read and delivered, so it was seen; this should have been rejected. |
| msquic | 2.7.0 (7e6525d) | Fail | Accepted a protocol violation and carried on. The anomaly was in the response the client read and delivered, so it was seen; 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. §7.2.7 leaves the maximum push ID unset until the client sends MAX_PUSH_ID, so a server "cannot push until it receives a MAX_PUSH_ID frame" and every push ID is larger than the client has advertised. WHERE the frame goes is the whole test. It was written to the control stream, where §7.2.5 gives a different and more specific answer -- a PUSH_PROMISE there is H3_FRAME_UNEXPECTED whatever its push ID -- so the port asked one question and this entry graded the other. Seven independent implementations answered 0x105 correctly and were failed for it, until 2026-09-20. It now arrives on the response stream, where the frame is legal and its push ID is the only thing left to object to. §7.2.5 is explicit about the answer: a client "MUST treat receipt of a PUSH_PROMISE frame that contains a larger push ID than the client has advertised as a connection error of H3_ID_ERROR".
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-promise-unsolicited")'