🐛 QUIC Hijack() skips the status-written check that HTTP/2 enforces
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- go
- Domain
- backend, networking
Research direction
Start by comparing http2RespWriter.Hijack in connection/http2.go with httpResponseAdapter.Hijack in connection/quic_connection.go, focusing on statusWritten and connectResponseSent. Reproduce the difference with the HTTP/2 and QUIC protocols and a backend returning 101. Done means both transports reject Hijack before their response has been sent and retain consistent behavior.
Written by the indexing model from the issue text.
Description
Describe the bug
Hijack() has different preconditions on the two transports.
HTTP/2, http2RespWriter.Hijack in connection/http2.go, refuses when no status was written yet:
if !rp.statusWritten {
return nil, nil, fmt.Errorf("status not yet written before attempting to hijack connection")
}
QUIC, httpResponseAdapter.Hijack in connection/quic_connection.go, has no such check. It always returns a localProxyConnection, even when connectResponseSent is still false, so the caller can write raw bytes to the stream before any connect response went out.
Same caller, different outcome depending on the transport: on HTTP/2 it gets an error, on QUIC it gets a conn.
To Reproduce
Stock cloudflared writes the status before it hijacks, so the built-in ingress path does not hit this. I hit it in a fork that replaces the OriginProxy, with code that hijacks first. net/http/httputil.ReverseProxy does exactly that on a 101: handleUpgradeResponse calls Hijack() and then writes the status line onto the conn itself.
ProxyHTTPserves the request throughhttputil.ReverseProxyto a backend that answers 101.- With
--protocol http2,Hijackfails and the client gets a 502. - With
--protocol quic,Hijacksucceeds and the caller can write to the stream before any connect response was sent.
Expected behavior
Both transports enforce the same precondition. The HTTP/2 check looks like the right one, so QUIC could refuse the same way while connectResponseSent is false.
Environment and versions
- OS: Linux
- Architecture: AMD64
- Version: 2026.9.1, and the
Hijackbodies are unchanged on master as of 2026.9.3
Logs and errors
HTTP/2: status not yet written before attempting to hijack connection. QUIC: no error.
Additional context
I worked around it on my side, so it does not block me. Filing it because the two transports disagree on the ResponseWriter contract, and that is easy to miss.
- Dominant language
- Go
- Stars
- 15.8k
- Forks
- 1.4k
- PR merge metrics
- No merged PRs in 30d
Getting set up
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from cloudflare/cloudflared
-
Priority: Normal Type: Bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
cloudflare/cloudflared#1747 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
cloudflare/cloudflared#1715 ·
-
Priority: Normal Type: Feature Request
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
cloudflare/cloudflared#1645 · 3 reactions ·
-
Priority: Normal Type: Bug
Difficulty 1/5 Under an hour Newbie friendliness 68/100
cloudflare/cloudflared#1609 · 1 reaction ·
-
Priority: Normal Type: Bug
Difficulty 1/5 Under an hour Newbie friendliness 68/100
cloudflare/cloudflared#1348 · 6 reactions ·
All issues in cloudflare/cloudflared
Similar issues
-
bug needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
DataDog/dd-trace-go#5469 ·
Maintainers usually reply within 1 day
-
bug tests
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
l3montree-dev/devguard#3101 ·
Maintainers usually reply within 1 day
-
area:*of bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
oapi-codegen/oapi-codegen#2593 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 85/100
DaoCloud/DaoCloud-docs#7432 ·
Maintainers usually reply within 1 day