{"record":{"id":"d7b71564ad2bb13a","repo":"dotnet/aspnetcore","slug":"the-server-responded-with-status-response-status","errorCode":null,"errorMessage":"The server responded with status ${response.status}.","messagePattern":"The server responded with status (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor.js","lineNumber":15,"sourceCode":"﻿const browserSupportsPasskeys =\n    typeof navigator.credentials !== 'undefined' &&\n    typeof window.PublicKeyCredential !== 'undefined' &&\n    typeof window.PublicKeyCredential.parseCreationOptionsFromJSON === 'function' &&\n    typeof window.PublicKeyCredential.parseRequestOptionsFromJSON === 'function';\n\nasync function fetchWithErrorHandling(url, options = {}) {\n    const response = await fetch(url, {\n        credentials: 'include',\n        ...options\n    });\n    if (!response.ok) {\n        const text = await response.text();\n        console.error(text);\n        throw new Error(`The server responded with status ${response.status}.`);\n    }\n    return response;\n}\n\nasync function createCredential(signal) {\n    const optionsResponse = await fetchWithErrorHandling('/Account/PasskeyCreationOptions', {\n        method: 'POST',\n        signal,\n    });\n    const optionsJson = await optionsResponse.json();\n    const options = PublicKeyCredential.parseCreationOptionsFromJSON(optionsJson);\n    return await navigator.credentials.create({ publicKey: options, signal });\n}\n\nasync function requestCredential(email, mediation, signal) {\n    const optionsResponse = await fetchWithErrorHandling(`/Account/PasskeyRequestOptions?username=${email}`, {\n        method: 'POST',\n        signal,","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor.js#L1-L33","documentation":"Thrown by fetchWithErrorHandling after a non-ok HTTP response from the passkey endpoints (/Account/PasskeyCreationOptions, /Account/PasskeyRequestOptions). The server returned an HTTP error status (4xx/5xx), so the passkey credential flow cannot proceed. The response body is logged to console.error before throwing.","triggerScenarios":"Calling fetchWithErrorHandling against /Account/PasskeyCreationOptions or /Account/PasskeyRequestOptions when the ASP.NET Core account endpoint returns non-2xx. Anti-forgery token failure (400), missing authentication (401), server exception (500), or endpoint not mapped (404) all hit this path.","commonSituations":"Anti-forgery cookie/token not sent because credentials:'include' is overridden by a same-origin policy change; the Blazor account endpoints were customized or removed; the user session expired mid-flow; ASP.NET Core rate limiting or authorization policies reject the request.","solutions":["Open DevTools Network tab, inspect the failing /Account/Passkey* request status and response body (already console.error'd) to identify the exact HTTP code.","If 400 Bad Request: verify the anti-forgery token is being sent (the form must include the request verification token and cookies:'include' must remain in effect).","If 401/403: confirm the user is still authenticated and the endpoint's [Authorize] policy is satisfied before invoking passkey UI.","If 404: confirm AddPasskey / MapPasskeyEndpoints is registered in Program.cs and the route matches '/Account/PasskeyCreationOptions'.","If 500: inspect the server-side exception in ASP.NET Core logs; the passkey options handler likely threw."],"exampleFix":"// before\nconst response = await fetch(url, { credentials: 'include', ...options });\nif (!response.ok) { /* generic throw */ }\n\n// after — surface server-provided error text to the UI\nasync function fetchWithErrorHandling(url, options = {}) {\n  const response = await fetch(url, { credentials: 'include', ...options });\n  if (!response.ok) {\n    const text = await response.text().catch(() => '');\n    throw new Error(`Passkey request to ${url} failed (${response.status}): ${text}`);\n  }\n  return response;\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight the endpoint is reachable & authed before offering passkey UI\nasync function canReachPasskeyEndpoint() {\n  try {\n    const r = await fetch('/Account/PasskeyCreationOptions', {\n      method: 'HEAD', credentials: 'include'\n    });\n    return r.ok || r.status === 405; // 405 = endpoint exists, HEAD not allowed\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await component.obtainAndSubmitCredential();\n} catch (e) {\n  if (/server responded with status (\\d+)/.test(e.message)) {\n    const status = RegExp.$1;\n    showUserError(status === 401 ? 'Session expired — please sign in again.' : 'Passkey request failed. Try a different sign-in method.');\n  } else throw e;\n}","preventionTips":["Ensure credentials:'include' is not overridden by callers spreading options.","Keep the anti-forgery token present in the form before triggering passkey submit.","Render a fallback login method so a server error is recoverable for the user."],"tags":["network","http","passkey","authentication","blazor"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}