What versions & operating system are you using?
- Wrangler 4.131.1 (also observed on 4.x generally),
compatibility_date
2026-01-01 (also observed with 2026-08-22 + nodejs_compat).
- Observed 2026-09-19/21 from EU colos (LIS), Workers Free plan account.
- Clients: curl 8.20 (forced
--http2) and Chrome 153 (HTTP/3).
Please provide a link to a minimal reproduction
https://github.com/sqrter/cf-held-response-repro
Describe the Bug
Summary
A worker whose requests perform serialized cross-request async work (each
request awaits, at its start, the flush of the previous request's queued
records through a promise chain held in isolate state) plus unawaited
background subrequests gets its requests silently canceled by the
platform. The client receives no response of any kind — no headers, no data,
no stream reset, no error page — and wrangler tail shows the canceled
requests did invoke the worker with outcome: "canceled" even though the
client stayed connected for the full timeout.
In the minimal form below, the effect is total: on a fresh deployment the first
request succeeds and every subsequent request — held or instant — receives
no response until a new deployment replaces the isolate. With a
differently-timed variant (per-request logger reconfiguration + timer-driven
background flush + responses held ≥ ~2.5s) the same mechanism instead dropped
roughly every second request while instant requests passed — severity depends
on timing/shape; the trigger family is the same.
This seems to be a platform bug: the client did nothing wrong, the worker completes
normally on the requests that are not canceled, and nothing in the documented
behavior suggests requests may be lost this way. The trigger pattern is what
common batched logging/telemetry pipelines do per request.
Production edge/runtime behavior (not a wrangler tooling issue): reproduces on a
live-deployed worker; wrangler tail shows outcome: "canceled" at 100%
invocation-log sampling while the client remained connected.
Minimal reproduction
Runnable project: https://github.com/sqrter/cf-held-response-repro
(three files: package.json, wrangler.toml, src/index.ts; zero runtime
dependencies — plain fetch + setTimeout + promise chains).
git clone https://github.com/sqrter/cf-held-response-repro
cd cf-held-response-repro
npm install && npx wrangler deploy
for i in $(seq 1 12); do
curl --http2 --max-time 12 -s -o /dev/null -w "cmd $i: %{http_code}\n" \
-X POST "https://<name>.workers.dev/command?delay=2500"
done
# in another terminal: npx wrangler tail
Real-world relevance
This pattern is what many logging/telemetry pipelines do per request (batch
records, flush asynchronously, dispose on the next cycle). It was originally
observed in production with a real logger + telemetry client; this repro
distills it to plain primitives so no third-party library is involved.
Please provide any relevant error logs
No response
What versions & operating system are you using?
compatibility_date2026-01-01 (also observed with 2026-08-22 +
nodejs_compat).--http2) and Chrome 153 (HTTP/3).Please provide a link to a minimal reproduction
https://github.com/sqrter/cf-held-response-repro
Describe the Bug
Summary
A worker whose requests perform serialized cross-request async work (each
request awaits, at its start, the flush of the previous request's queued
records through a promise chain held in isolate state) plus unawaited
background subrequests gets its requests silently canceled by the
platform. The client receives no response of any kind — no headers, no data,
no stream reset, no error page — and
wrangler tailshows the canceledrequests did invoke the worker with
outcome: "canceled"even though theclient stayed connected for the full timeout.
In the minimal form below, the effect is total: on a fresh deployment the first
request succeeds and every subsequent request — held or instant — receives
no response until a new deployment replaces the isolate. With a
differently-timed variant (per-request logger reconfiguration + timer-driven
background flush + responses held ≥ ~2.5s) the same mechanism instead dropped
roughly every second request while instant requests passed — severity depends
on timing/shape; the trigger family is the same.
This seems to be a platform bug: the client did nothing wrong, the worker completes
normally on the requests that are not canceled, and nothing in the documented
behavior suggests requests may be lost this way. The trigger pattern is what
common batched logging/telemetry pipelines do per request.
Minimal reproduction
Runnable project: https://github.com/sqrter/cf-held-response-repro
(three files:
package.json,wrangler.toml,src/index.ts; zero runtimedependencies — plain
fetch+setTimeout+ promise chains).Real-world relevance
This pattern is what many logging/telemetry pipelines do per request (batch
records, flush asynchronously, dispose on the next cycle). It was originally
observed in production with a real logger + telemetry client; this repro
distills it to plain primitives so no third-party library is involved.
Please provide any relevant error logs
No response