{"record":{"id":"ead0bdca906c7cad","repo":"dotnet/aspnetcore","slug":"the-required-antiforgery-request-token-was-not-pro","errorCode":null,"errorMessage":"The required antiforgery request token was not provided in either form field \"{0}\" or header value \"{1}\".","messagePattern":"The required antiforgery request token was not provided in either form field \"(.+?)\" or header value \"(.+?)\"\\.","errorType":"exception","errorClass":"AntiforgeryValidationException","httpStatus":null,"severity":"error","filePath":"src/Antiforgery/src/Internal/DefaultAntiforgery.cs","lineNumber":169,"sourceCode":"\n        if (tokens.RequestToken == null)\n        {\n            if (_options.HeaderName == null)\n            {\n                var message = Resources.FormatAntiforgery_FormToken_MustBeProvided(_options.FormFieldName);\n                throw new AntiforgeryValidationException(message);\n            }\n            else if (!httpContext.Request.HasFormContentType)\n            {\n                var message = Resources.FormatAntiforgery_HeaderToken_MustBeProvided(_options.HeaderName);\n                throw new AntiforgeryValidationException(message);\n            }\n            else\n            {\n                var message = Resources.FormatAntiforgery_RequestToken_MustBeProvided(\n                    _options.FormFieldName,\n                    _options.HeaderName);\n                throw new AntiforgeryValidationException(message);\n            }\n        }\n\n        ValidateTokens(httpContext, tokens);\n\n        _logger.ValidatedAntiforgeryToken();\n    }\n\n    private void ValidateTokens(HttpContext httpContext, AntiforgeryTokenSet antiforgeryTokenSet)\n    {\n        Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.CookieToken));\n        Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.RequestToken));\n\n        // Extract cookie & request tokens\n        AntiforgeryToken deserializedCookieToken;\n        AntiforgeryToken deserializedRequestToken;\n\n        DeserializeTokens(","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Antiforgery/src/Internal/DefaultAntiforgery.cs#L151-L187","documentation":"Thrown by DefaultAntiforgery.ValidateRequestAsync when no request token is found in the incoming POST. The system first checks the configured header (if HeaderName is set), then falls back to the form body field; when neither contains a token and the request has a form content type, this combined message is produced. It indicates the client sent a state-changing request without the antiforgery request token that pairs with the cookie token. The exception type is AntiforgeryValidationException.","triggerScenarios":"A non-safe HTTP method (POST/PUT/DELETE/PATCH) is sent, the antiforgery cookie is present, but neither the configured header nor the form field (_options.FormFieldName, default \"__RequestVerificationToken\") contains a value. This branch fires specifically when _options.HeaderName is non-null AND the request HasFormContentType, yet the form field is empty.","commonSituations":"An AJAX/fetch POST that forgets to add the antiforgery header; a form rendered without the asp-antiforgery token tag helper; renaming the form field via AntiforgeryOptions.FormFieldName so the client sends the old name; a SPA sending JSON where the token is expected in a header but HeaderName was left null and the body is application/json (no form content type).","solutions":["Ensure the request includes the token: for forms use the asp-action tag helper which auto-renders a hidden <input name=\"__RequestVerificationToken\">; for AJAX read the token emitted by IAntiforgery.GetAndStoreTokens and send it in the header named in AntiforgeryOptions.HeaderName.","Verify the form field name matches _options.FormFieldName (default \"__RequestVerificationToken\") and the header name matches _options.HeaderName.","If this is a JSON-body request, set HeaderName in AntiforgeryOptions and add the token as a request header from the client, since the form body won't be read for application/json.","Confirm the middleware pipeline includes AddAntiforgery/UseAntiforgery and that tokens were generated (GetAndStoreTokens) and sent to the client in the prior GET."],"exampleFix":"// before (AJAX without token)\nfetch('/api/save', { method: 'POST', body: JSON.stringify(data),\n  headers: { 'Content-Type': 'application/json' } });\n\n// after — send token in the configured header\nconst token = document.querySelector('input[name=\"__RequestVerificationToken\"]').value;\nfetch('/api/save', { method: 'POST', body: JSON.stringify(data),\n  headers: { 'Content-Type': 'application/json',\n             'RequestVerificationToken': token } });","handlingStrategy":"try-catch","validationCode":"// Ensure token is available before POSTing\nfunction getAntiForgeryToken() {\n  const input = document.querySelector('input[name=\"__RequestVerificationToken\"]');\n  if (!input || !input.value) {\n    throw new Error('Antiforgery token missing from page');\n  }\n  return input.value;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    await _antiforgery.ValidateRequestAsync(HttpContext);\n}\ncatch (AntiforgeryValidationException ex)\n{\n    _logger.LogWarning(ex, \"Antiforgery validation failed\");\n    return BadRequest(\"Invalid or missing antiforgery token.\");\n}","preventionTips":["Always render antiforgery tokens in forms via tag helpers or GetAndStoreTokens.","For SPA/AJAX, configure HeaderName and include the token in every state-changing request header.","Use [AutoValidateAntiforgeryToken] globally so no POST is accidentally left unprotected."],"tags":["antiforgery","security","csrf","aspnetcore","http-request"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}