From 4e274f0ddac0e70f1bf096a8186c19b98e910204 Mon Sep 17 00:00:00 2001 From: assim Date: Tue, 7 Apr 2026 15:19:33 +0100 Subject: [PATCH 1/2] fix(miniflare): prevent fetch failed on POST 401 responses When a Worker returns a 401 response to a POST request, undici Fetch spec implementation (step 14) triggers HTTP authentication retry logic. It attempts to re-extract the request body source for re-sending with credentials, but workerd uses streamed request bodies where body.source is null. This causes undici to throw a network error: "expected non-null body source", surfacing as "TypeError: fetch failed". Fix: Set credentials to "omit" in miniflare fetch wrapper when calling undici.fetch(). This bypasses the 401 authentication retry entirely. Miniflare dispatches to the workerd runtime directly - there is no HTTP authentication scheme to negotiate, so this code path should never trigger. Verified: the fix resolves POST 401 crashes while preserving correct behavior for POST 200, POST 400, POST 403, POST 500, and GET 401. Fixes #13327 --- packages/miniflare/src/http/fetch.ts | 9 +++++++++ packages/miniflare/src/index.ts | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/packages/miniflare/src/http/fetch.ts b/packages/miniflare/src/http/fetch.ts index 8343f26a20..08df48222c 100644 --- a/packages/miniflare/src/http/fetch.ts +++ b/packages/miniflare/src/http/fetch.ts @@ -83,6 +83,15 @@ export async function fetch( const response = await undici.fetch(request, { dispatcher: requestInit?.dispatcher, + // Prevent undici's HTTP 401 authentication retry logic from triggering. + // When a POST request with a streamed body (body.source === null) receives + // a 401, undici tries to re-extract the request body for re-sending with + // credentials, but fails with "expected non-null body source" because + // workerd uses streamed bodies. Setting credentials to "omit" bypasses + // the 401 handling entirely (Fetch spec §4.4 step 14). This is safe + // because miniflare dispatches to workerd directly — there is no HTTP + // authentication to retry. + credentials: "omit", }); return new Response(response.body, response); } diff --git a/packages/miniflare/src/index.ts b/packages/miniflare/src/index.ts index 76cf0c9c2b..5da4c0030d 100644 --- a/packages/miniflare/src/index.ts +++ b/packages/miniflare/src/index.ts @@ -2707,6 +2707,14 @@ export class Miniflare { const forwardInit = forward as RequestInit; forwardInit.dispatcher = dispatcher; + // Omit credentials to prevent undici's HTTP 401 authentication retry + // logic from triggering. When a POST request with a streamed body + // receives a 401, undici tries to re-extract the body source for + // credential re-authentication. Since workerd uses streamed bodies + // (body.source === null), this causes a "fetch failed" network error + // with "expected non-null body source". Setting credentials to "omit" + // bypasses the 401 handling entirely (see Fetch spec step 14). + forwardInit.credentials = "omit"; const response = await fetch(url, forwardInit); // If the Worker threw an uncaught exception, propagate it to the caller From 39dedbb2c6367db70942502fe2ced6593f7caafb Mon Sep 17 00:00:00 2001 From: assim Date: Tue, 7 Apr 2026 15:41:37 +0100 Subject: [PATCH 2/2] add changeset --- .changeset/fix-miniflare-post-401.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/fix-miniflare-post-401.md diff --git a/.changeset/fix-miniflare-post-401.md b/.changeset/fix-miniflare-post-401.md new file mode 100644 index 0000000000..d15ab91c9f --- /dev/null +++ b/.changeset/fix-miniflare-post-401.md @@ -0,0 +1,7 @@ +--- +"miniflare": patch +--- + +fix(miniflare): prevent fetch failed on POST 401 responses + +Set `credentials: "omit"` in miniflare's fetch wrapper to bypass undici's HTTP 401 authentication retry logic. Workerd uses streamed request bodies where `body.source` is null, causing undici to throw "expected non-null body source" on POST 401 responses.