dotnet/aspnetcore · error

Enhanced navigation does not support making a non-GET reques

Error message

Enhanced navigation does not support making a non-GET request to a non-Blazor endpoint. Avoid enabling enhanced navigation for forms that post to a non-Blazor endpoint.

What it means

Thrown by performEnhancedPageLoad (NavigationEnhancement.ts:258) when a non-GET (POST/PUT/etc.) enhanced form submission receives a success (2xx) response from an endpoint that is not a Blazor endpoint (identified by the missing 'blazor-enhanced-nav: allow' response header). Blazor refuses to patch arbitrary non-Blazor HTML into its DOM via a non-idempotent request because it cannot safely retry the POST as a full page load.

Source

Thrown at src/Components/Web.JS/src/Services/NavigationEnhancement.ts:258

        } else {
          throw new Error('Enhanced navigation does not support making a non-GET request to an endpoint that redirects to an external origin. Avoid enabling enhanced navigation for form posts that may perform external redirections.');
        }
      }

      if (isSuccessResponse && response.headers.get('blazor-enhanced-nav') !== 'allow') {
        // This appears to be a non-Blazor-Endpoint success response. We don't want to use enhanced nav
        // because the content we receive is not designed to be patched into an existing frame,
        // and may be incompatible with the Blazor JS that's already here.
        // The reason we don't apply the same logic for non-success responses is that:
        //  - We don't want to retry as then developers will get double-failures in logs
        //  - We really want to show error pages to avoid losing vital debugging info
        // ... and since error pages can be considered terminally fatal, we don't have to worry about
        // whether the page has complex client-side behaviors that are incompatible with our JS.
        if (isGetRequest) {
          retryEnhancedNavAsFullPageLoad(internalDestinationHref);
          return;
        } else {
          throw new Error('Enhanced navigation does not support making a non-GET request to a non-Blazor endpoint. Avoid enabling enhanced navigation for forms that post to a non-Blazor endpoint.');
        }
      }

      // For 301/302/etc redirections to internal URLs, the browser will already have followed the chain of redirections
      // to the end, and given us the final content. We do still need to update the current URL to match the final location,
      // then let the rest of enhanced nav logic run to patch the new content into the DOM.
      if (changeUrl && (response.redirected || treatAsRedirectionFromMethod)) {
        const treatAsGet = treatAsRedirectionFromMethod ? (treatAsRedirectionFromMethod === 'get') : isGetRequest;
        if (treatAsGet) {
          // For gets, the intermediate (redirecting) URL is already in the address bar, so we have to use 'replace'
          // so that 'back' would go to the page before the redirection
          history.replaceState(null, '', response.url);
        } else {
          // For non-gets, we're still on the source page, so need to append a whole new history entry
          if (response.url !== location.href) {
            history.pushState(null, '', response.url);
          }
        }

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Remove data-enhance from forms posting to non-Blazor endpoints.
  2. Ensure the target endpoint goes through app.MapRazorComponents / the Blazor endpoints middleware so it emits blazor-enhanced-nav: allow.
  3. Change the form method to 'get' if the endpoint supports it.
  4. Post to a Blazor endpoint that participates in enhanced navigation.

Example fix

<!-- before: enhanced form to legacy MVC -->
<form method="post" data-enhance action="/legacy/submit">

<!-- after -->
<form method="post" action="/legacy/submit">
<!-- or route the action through a Blazor component endpoint -->
Defensive patterns

Strategy: validation

Validate before calling

function isBlazorEndpointCandidate(actionUrl: string): boolean {
  // only heuristic; real check is the response header 'blazor-enhanced-nav: allow'
  return actionUrl.startsWith(document.baseURI);
}

Type guard

function isEnhancedNavAllowedResponse(res: Response): boolean {
  return res.headers.get('blazor-enhanced-nav') === 'allow';
}

Try / catch

try {
  await performEnhancedPageLoad(url, false, fetchOptions);
} catch (e) {
  if (/non-Blazor endpoint/.test((e as Error).message)) {
    // resubmit natively without enhanced nav
  } else { throw e; }
}

Prevention

When it happens

Trigger: An enhanced form (data-enhance) with method POST/etc. whose action targets a non-Blazor endpoint (static file, MVC without the Blazor middleware, external API proxied locally, or an endpoint that doesn't set the blazor-enhanced-nav header).

Common situations: Posting an enhanced Blazor form to a legacy MVC controller, a static HTML handler, a different ASP.NET Core app without the Blazor endpoint middleware, or an API endpoint; forgetting to add Blazor endpoints middleware to that route.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/bf5f1ed2a0357d2f. Report an issue: GitHub.