Skip to content

On cross-request async work + unawaited background subrequests -> subsequent requests silently canceled #15753

Description

@sqrter

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    upstream:workerdRoot cause is in the workerd runtime: https://github.com/cloudflare/workerd

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions