{"record":{"id":"f7f51e08b18eab4e","repo":"dotnet/AspNetCore.Docs","slug":"validation-failed-status-code-response-statusco","errorCode":null,"errorMessage":"Validation failed. Status Code: {response.StatusCode}","messagePattern":"Validation failed\\. Status Code: (.+?)","errorType":"http","errorClass":"HttpRequestException","httpStatus":null,"severity":"error","filePath":"aspnetcore/blazor/forms/validation.md","lineNumber":1498,"sourceCode":"        customValidation?.ClearErrors();\n\n        try\n        {\n            using var response = await Http.PostAsJsonAsync<Starship>(\n                \"StarshipValidation\", (Starship)editContext.Model);\n\n            var errors = await response.Content\n                .ReadFromJsonAsync<Dictionary<string, List<string>>>() ?? \n                new Dictionary<string, List<string>>();\n\n            if (response.StatusCode == HttpStatusCode.BadRequest && \n                errors.Any())\n            {\n                customValidation?.DisplayErrors(errors);\n            }\n            else if (!response.IsSuccessStatusCode)\n            {\n                throw new HttpRequestException(\n                    $\"Validation failed. Status Code: {response.StatusCode}\");\n            }\n            else\n            {\n                disabled = true;\n                messageStyles = \"color:green\";\n                message = \"The form has been processed.\";\n            }\n        }\n        catch (AccessTokenNotAvailableException ex)\n        {\n            ex.Redirect();\n        }\n        catch (Exception ex)\n        {\n            Logger.LogError(\"Form processing error: {Message}\", ex.Message);\n            disabled = true;\n            messageStyles = \"color:red\";","sourceCodeStart":1480,"sourceCodeEnd":1516,"githubUrl":"https://github.com/dotnet/AspNetCore.Docs/blob/c67a80103a1a74db20784debd919c7fdda96c510/aspnetcore/blazor/forms/validation.md#L1480-L1516","documentation":"Thrown by client-side form submission code when the server returns a non-success status code that is NOT a 400 BadRequest carrying a parseable validation error dictionary. The code first attempts to read a Dictionary<string,List<string>> of field errors from a 400 response; only if that branch does not match does it throw an HttpRequestException with the raw status code. It exists to surface server-side validation failures that the client cannot display inline.","triggerScenarios":"Posting a form via HttpClient.PostAsJsonAsync and receiving any non-2xx, non-400 response (e.g. 401 Unauthorized, 403 Forbidden, 404, 500, 502, 503). Also triggered when the response IS 400 but ReadFromJsonAsync returns an empty dictionary (errors.Any() is false), or returns null and the dictionary is empty. A malformed JSON body on a 400 also routes here if the parsed dictionary is empty.","commonSituations":"Authentication/authorization failures (token expired, cookie missing) on the form-submit endpoint; server throws an unhandled exception returning 500; downstream API behind the endpoint is unreachable (502/503); anti-forgery token validation fails returning 400 with a body shape that does not deserialize to Dictionary<string,List<string>>; the endpoint route changed and returns 404.","solutions":["Inspect response.StatusCode in the debugger or log it to identify the exact failure (401/500/404 etc.) and fix the corresponding server-side cause.","Confirm the server endpoint returns BadRequest(errors) with a Dictionary<string,List<string>> shape so that the 400 branch displays field errors instead of throwing.","If the 400 body uses a different shape (e.g. ProblemDetails or string array), adjust ReadFromJsonAsync<T> and customValidation.DisplayErrors to match, or map it into the expected dictionary.","Verify authentication state and anti-forgery token are sent with the request when the endpoint is protected.","Catch HttpRequestException in the calling component and present a user-facing message rather than letting it bubble to the Blazor error boundary."],"exampleFix":"// before\nelse if (!response.IsSuccessStatusCode)\n{\n    throw new HttpRequestException(\n        $\"Validation failed. Status Code: {response.StatusCode}\");\n}\n\n// after\nelse if (!response.IsSuccessStatusCode)\n{\n    messageStyles = \"color:red\";\n    message = response.StatusCode == System.Net.HttpStatusCode.Unauthorized\n        ? \"You must be signed in to submit the form.\"\n        : $\"The request failed ({(int)response.StatusCode}). Please try again.\";\n    logger.LogError(\"Form submit failed: {StatusCode}\", response.StatusCode);\n}","handlingStrategy":"try-catch","validationCode":"// Validate before submit: ensure endpoint reachable and auth present\nif (customValidation is null)\n{\n    // configure a validation display target before calling\n}\nvar response = await Http.PostAsJsonAsync(\"/api/submit\", model);\nif (!response.IsSuccessStatusCode && response.StatusCode != HttpStatusCode.BadRequest)\n{\n    // surface a user-facing message instead of throwing\n}","typeGuard":"static bool IsRecoverable(HttpStatusCode sc) =>\n    sc == HttpStatusCode.BadRequest || (int)sc is >= 500 and <= 599;","tryCatchPattern":"try { var response = await Http.PostAsJsonAsync(...); /* branch on status */ }\ncatch (HttpRequestException ex)\n{\n    messageStyles = \"color:red\";\n    message = \"Submission failed. Please try again later.\";\n    logger.LogError(ex, \"Form submission HTTP failure.\");\n}","preventionTips":["Confirm the server endpoint returns BadRequest(Dictionary<string,List<string>>) for validation errors.","Send anti-forgery tokens and auth credentials with protected form posts.","Log response.StatusCode before throwing to speed diagnosis.","Catch HttpRequestException at the component boundary and render a user-friendly message."],"tags":["blazor","http","validation","forms","httprequestexception"],"backgroundTag":null,"analyzedSha":"c67a80103a1a74db20784debd919c7fdda96c510","analyzedAt":"2026-08-13T17:46:11.763Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}