dotnet/runtime · error · Error

This browser doesn't support fetch API. Please use a modern

Error message

This browser doesn't support fetch API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms

What it means

verifyEnvironment detects a non-Node (browser) host where global fetch is missing, meaning the browser/engine is too old to support the Fetch API that the .NET WASM HttpClient depends on. The message directs users to the Blazor supported-platforms doc.

Source

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

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import BuildConfiguration from "consts:configuration";

import type { VoidPtr, ControllablePromise } from "./types";

import { wrapAsCancelablePromise } from "./cancelable-promise";
import { ENVIRONMENT_IS_NODE } from "./per-module";
import { assertJsInterop } from "./utils";
import { MemoryViewType, Span } from "./marshaled-types";
import { dotnetLogger, dotnetAssert } from "./cross-module";


function verifyEnvironment() {
    if (typeof globalThis.fetch !== "function" || typeof globalThis.AbortController !== "function") {
        const message = ENVIRONMENT_IS_NODE
            ? "Please install `node-fetch` and `node-abort-controller` npm packages to enable HTTP client support."
            : "This browser doesn't support fetch API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms";
        throw new Error(message);
    }
}

function commonAsserts(controller: HttpController) {
    if (BuildConfiguration !== "Debug") {
        return;
    }
    assertJsInterop();
    dotnetAssert.check(controller, "expected controller");
}

export function httpSupportsStreamingRequest(): boolean {
    // Detecting streaming request support works like this:
    // If the browser doesn't support a particular body type, it calls toString() on the object and uses the result as the body.
    // So, if the browser doesn't support request streams, the request body becomes the string "[object ReadableStream]".
    // When a string is used as a body, it conveniently sets the Content-Type header to text/plain;charset=UTF-8.
    // So, if that header is set, then we know the browser doesn't support streams in request objects, and we can exit early.

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Run the app in a supported modern browser (see the Blazor supported-platforms doc).
  2. If you must support an old engine, polyfill fetch and AbortController globally before runtime init.
  3. Detect missing fetch on load and show end users a clear upgrade message.

Example fix

// before: app loads in an old WebView -> throws on first HTTP call

// after: feature-detect and block/polyfill
if (typeof window.fetch !== "function") {
  showUpgradeNotice(); // or load a fetch polyfill
}
Defensive patterns

Strategy: validation

Validate before calling

if (typeof globalThis.fetch !== "function") {
  showUpgradeNotice("This app needs a browser with Fetch support.");
}

Prevention

When it happens

Trigger: Loading the .NET WASM app in a browser or WebView that lacks a global fetch function — old Safari, a legacy embedded WebView, or a stripped-down automation engine.

Common situations: Legacy enterprise browsers; old mobile WebViews; embedded devices with outdated browser engines; browser automation against a minimal engine.

Related errors


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