Skip to content

@sentry/cloudflare: root http.server span lost on streaming responses exceeding ctx.waitUntil 30s budget (regression since 10.28.0) #20409

@Kobby-Bawuah

Description

@Kobby-Bawuah

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/cloudflare

SDK Version

10.28.0 through 10.49.0 (current develop). Regression introduced in 10.28.0, still present.

Framework Version

N/A — reproducible directly against @sentry/cloudflare. Framework wrappers that route through wrapRequestHandler (e.g. @sentry/remix/cloudflare, @sentry/hono/cloudflare) are expected to be affected as well but not directly verified.

Link to Sentry event

No response

Reproduction Example/SDK Setup

import * as Sentry from '@sentry/cloudflare';

export default Sentry.withSentry(
(env) => ({ dsn: env.SENTRY_DSN, tracesSampleRate: 1.0 }),
{
async fetch(request, env, ctx) {
// Any upstream producing a streaming body that takes >30s to fully emit
// (e.g. LLM chat completion over SSE).
const upstream = await fetch('https://example.com/long-sse-endpoint');
return new Response(upstream.body, {
headers: { 'content-type': 'text/event-stream' },
});
},
},
);

Steps to Reproduce

  1. Deploy a Cloudflare Worker using @sentry/cloudflare ≥ 10.28.0 with tracesSampleRate: 1.0.
  2. Have the handler return a response whose Content-Type is classified as streaming by classifyResponseStreaming()text/event-stream, application/x-ndjson, application/stream+json, or text/plainwithoutContent-Length`.
  3. Ensure the upstream response body takes longer than ~30 seconds to fully emit (the mechanism depends on upstream-body duration, not on whether the client disconnects).
  4. Observe span reporting for these requests.

Expected Result

Root http.server span is reported for every request, as on @sentry/cloudflare < 10.28.0.

Actual Result

Root http.server span is silently dropped for requests whose upstream body duration exceeds the ctx.waitUntil 30s shared budget. Cloudflare emits the documented warning to Workers Logs:
waitUntil() tasks did not complete within the allowed time after invocation end and have been cancelled.

Observable signature when comparing pre-10.28 vs post-10.28 telemetry on the same streaming endpoint:
Pre-10.28: p95 span.duration reflects handler-return time (often single-digit seconds for endpoints that return a streaming body quickly).
Post-10.28: p95 span.duration on landed spans sits just below the 30s waitUntil cap; requests whose upstream body takes longer than 30s never produce a span.

Additional Context

I think this was introduced by:

#18087 — fix(cloudflare): Keep http root span alive until streaming responses are consumed
#18334 — fix(cloudflare): Wait for async events to finish

Both merged into 10.28.0.

Priority

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it.

Metadata

Metadata

Assignees

No one assigned
    No fields configured for issues without a type.

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions