dotnet/runtime · error · Error

BrowserHttpWriteStream.Rejected

Error message

BrowserHttpWriteStream.Rejected

What it means

While streaming a request body in httpTransformStreamWrite, awaiting streamWriter.ready then streamWriter.write(copy) rejected. The interop deliberately throws the generic message 'BrowserHttpWriteStream.Rejected', hiding the underlying network/protocol error from the .NET side; the real cause is logged via the muted debug log.

Source

Thrown at src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/http.ts:110

    } catch (err) {
        // ignore
    }
}

export function httpTransformStreamWrite(controller: HttpController, bufferPtr: VoidPtr, bufferLength: number): ControllablePromise<void> {
    commonAsserts(controller);
    dotnetAssert.check(bufferLength > 0, "expected bufferLength > 0");
    // the bufferPtr is pinned by the caller
    const view = new Span(bufferPtr, bufferLength, MemoryViewType.Byte);
    const copy = view.slice() as Uint8Array;
    return wrapAsCancelablePromise(async () => {
        dotnetAssert.check(controller.streamWriter, "expected streamWriter");
        dotnetAssert.check(controller.responsePromise, "expected fetch promise");
        try {
            await controller.streamWriter.ready;
            await controller.streamWriter.write(copy);
        } catch (ex) {
            throw new Error("BrowserHttpWriteStream.Rejected");
        }
    });
}

export function httpTransformStreamClose(controller: HttpController): ControllablePromise<void> {
    dotnetAssert.check(controller, "expected controller");
    return wrapAsCancelablePromise(async () => {
        dotnetAssert.check(controller.streamWriter, "expected streamWriter");
        dotnetAssert.check(controller.responsePromise, "expected fetch promise");
        try {
            await controller.streamWriter.ready;
            await controller.streamWriter.close();
        } catch (ex) {
            throw new Error("BrowserHttpWriteStream.Rejected");
        }
    });
}

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Confirm the server actually accepts streamed (duplex/chunked) request bodies and that headers are valid.
  2. Retry the upload with a non-streaming buffered body via httpFetchBytes instead of httpFetchStream.
  3. Inspect the 'http muted: ...' debug log (dotnetLogger.debug) for the real underlying error.
  4. Verify the network/proxy permits chunked uploads and isn't timing out.

Example fix

// before: streaming upload the server/proxy rejects
httpFetchStream(controller, url, ...); // server resets -> BrowserHttpWriteStream.Rejected

// after: fall back to buffered upload
httpFetchBytes(controller, url, headers, hVals, opts, oVals, bodyPtr, bodyLength);
Defensive patterns

Strategy: try-catch

Try / catch

try { await httpTransformStreamWrite(controller, ptr, len).promise; }
catch {
  // stream errored — fall back to buffered upload or surface to the .NET caller
  await httpFetchBytes(controller, url, headers, hVals, opts, oVals, bodyPtr, bodyLength).promise;
}

Prevention

When it happens

Trigger: The server closed/refused the connection mid-upload, the writable stream entered an errored state, the AbortController aborted during a streamed upload, or httpTransformStreamWrite was called after the stream was already errored.

Common situations: Streaming upload to an endpoint that rejects streamed/chunked bodies; a proxy/CDN that buffers and drops large requests; server-side request-size limits; TLS/connection reset mid-stream.

Related errors


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/07caaa5837523574. Report an issue: GitHub.