dotnet/aspnetcore · error · Error
Enhanced navigation does not support making a non-GET…
Error message
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.
What it means
Enhanced navigation in Blazor intercepts form submissions and link clicks and fetches the response via the Fetch API. When the server responds with a redirect to an external origin, the browser follows it in no-cors mode and the response becomes 'opaque', hiding the destination. For GET requests Blazor transparently falls back to a full page load, but for non-GET (POST/PUT/etc.) requests it cannot safely replay the form, so it throws this error rather than silently doing the wrong thing.
Solutions
- Do not enable enhanced navigation (data-enhance / Blazor enhanced form) on forms that may redirect to an external origin; let them do a normal full POST.
- Change the form's method to 'get' if appropriate, or remove its action so Blazor's enhanced nav is bypassed for that submit.
- Handle external redirects as a two-step: POST to your own endpoint, then return a client-side trigger (e.g. a link) the user clicks to leave the app.
- If you must POST then go external, perform the redirect from the client after the fetch resolves instead of via a server 30x.
Example fix
<!-- before: enhanced form posts then redirects externally --> <form method="post" data-enhance="true" action="/pay">...</form> <!-- after: do not enhance forms that leave the origin --> <form method="post" action="/pay">...</form>
Defensive patterns
Strategy: validation
Validate before calling
// Before enhancing a form, ensure its POST never redirects externally
function isSafeToEnhance(form: HTMLFormElement): boolean {
// Heuristic: do not enhance forms whose handler may hand off externally
const externalHandoff = form.dataset['externalHandoff'];
return form.method.toLowerCase() !== 'post' || externalHandoff !== 'true';
}
if (!isSafeToEnhance(form)) form.removeAttribute('data-enhance'); Try / catch
try {
await enhancedNavSubmit(form);
} catch (e) {
if (/external origin/i.test((e as Error).message)) {
// fall back to a non-enhanced submit
form.removeAttribute('data-enhance');
(form as HTMLFormElement & { submit(): void }).submit();
} else throw e;
} Prevention
- Do not mark forms that POST to endpoints which redirect externally as enhanced.
- For external handoffs (payments, SSO), perform the redirect from the client after a successful fetch.
- Prefer GET or no-action forms when using enhanced navigation.
- Document which endpoints may redirect externally in your routing layer.
When it happens
Trigger: Thrown at line 241 when response.type === 'opaque' (external-origin redirect detected) AND isGetRequest is false — i.e. an enhanced form POST reached an endpoint that 301/302-redirected to a different origin.
Common situations: A Blazor enhanced form whose POST handler redirects to an external payment provider / SSO / third-party URL; mixing enhanced navigation with forms that hand off to external services; a [HttpPost] endpoint that returns Redirect(...) to an absolute external URL.
Related errors
- Cannot perform enhanced form submission that changes the…
- Enhanced navigation does not support making a non-GET…
- No enhanced programmatic navigation handler has been…
- ' ' is flagged with SingleDelivery, but the selected…
- A public property ' ' on component type ' ' with a public…
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/461c6c49ca5cdc3b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Web.JS/src/Services/NavigationEnhancement.ts:241
}, fetchOptions));
let isNonRedirectedPostToADifferentUrlMessage: string | null = null;
await getResponsePartsWithFraming(
responsePromise, abortSignal,
(response, initialContent) => {
const isGetRequest = !fetchOptions?.method || fetchOptions.method === 'get';
const isSuccessResponse = response.status >= 200 && response.status < 300;
// For true 301/302/etc redirections to external URLs, we'll receive an opaque response
// (even if it has CORS enabled, since we passed no-cors), and the browser won't disclose
// the target URL to JS code. We must therefore retry as a non-enhanced-nav page load to reach
// the destination. This also has the benefit that we can be certain not to introduce content
// from an external origin into the DOM here.
if (response.type === 'opaque') {
if (isGetRequest) {
retryEnhancedNavAsFullPageLoad(internalDestinationHref);
return;
} 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.');
}View on GitHub (pinned to 3600ca084e)