{"record":{"id":"2d2072a272979b62","repo":"dotnet/aspnetcore","slug":"the-required-antiforgery-form-field-0-is-not-p","errorCode":null,"errorMessage":"The required antiforgery form field \"{0}\" is not present.","messagePattern":"The required antiforgery form field \"(.+?)\" is not present\\.","errorType":"validation","errorClass":"AntiforgeryValidationException","httpStatus":null,"severity":"error","filePath":"src/Antiforgery/src/Internal/DefaultAntiforgery.cs","lineNumber":157,"sourceCode":"    public async Task ValidateRequestAsync(HttpContext httpContext)\n    {\n        ArgumentNullException.ThrowIfNull(httpContext);\n\n        CheckSSLConfig(httpContext);\n\n        var tokens = await _tokenStore.GetRequestTokensAsync(httpContext);\n        if (tokens.CookieToken == null)\n        {\n            throw new AntiforgeryValidationException(\n                Resources.FormatAntiforgery_CookieToken_MustBeProvided(_options.Cookie.Name));\n        }\n\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();","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Antiforgery/src/Internal/DefaultAntiforgery.cs#L139-L175","documentation":"Thrown during antiforgery validation when the request token is missing and the application has NOT configured a header name (HeaderName == null), meaning antiforgery expects the token only as a form field. The validator already confirmed the cookie token exists, but the form field named in FormFieldName was absent. It is an AntiforgeryValidationException surfaced to the request pipeline as a 400.","triggerScenarios":"Calling ValidateAsync(httpContext) or letting the [ValidateAntiForgeryToken] filter run, when _options.HeaderName is null and the posted form does not contain the FormFieldName key (e.g. a form rendered without @Html.AntiForgeryToken() / <form> tag helper with asp-antiforgery, or a fetch POST that did not include the token field).","commonSituations":"Razor form rendered manually without the antiforgery tag helper; AJAX/fetch POST sending JSON or FormData that omits the hidden __RequestVerificationToken; a form field name misconfiguration between client and server; SPA posting to an MVC endpoint without copying the token into the body.","solutions":["Ensure the form is generated with the asp-antiforgery-enabled form tag helper or @Html.AntiForgeryToken() so the hidden field matching FormFieldName (default __RequestVerificationToken) is emitted.","For AJAX/fetch, read the hidden field from the DOM and include it in the submitted FormData or request body under the same field name.","If your client sends the token via an HTTP header instead, configure AntiforgeryOptions.HeaderName (e.g. options.HeaderName = \"RequestVerificationToken\") so validation looks in the header rather than the form.","Verify AntiforgeryOptions.FormFieldName on the server matches the field name the client actually sends."],"exampleFix":"// before: fetch missing token\nawait fetch('/submit', { method:'POST', body: JSON.stringify(data), headers:{'Content-Type':'application/json'} });\n\n// after: include antiforgery field in FormData\nconst token = document.querySelector('input[name=\"__RequestVerificationToken\"]').value;\nconst fd = new FormData();\nfd.append('__RequestVerificationToken', token);\nfd.append('payload', JSON.stringify(data));\nawait fetch('/submit', { method:'POST', body: fd });","handlingStrategy":"validation","validationCode":"// Before calling an endpoint protected by antiforgery, confirm the token field exists and is non-empty.\nconst field = document.querySelector('input[name=\"__RequestVerificationToken\"]');\nif (!field || !field.value) { /* regenerate form or fetch token */ }","typeGuard":null,"tryCatchPattern":"try { await antiforgery.ValidateRequestAsync(httpContext); }\ncatch (AntiforgeryValidationException) { return Results.BadRequest(\"Antiforgery token missing.\"); }","preventionTips":["Always render forms with the form tag helper or @Html.AntiForgeryToken().","For AJAX, read the hidden field or cookie and send it on every unsafe verb.","Keep FormFieldName consistent across server config and client code.","Add an integration test that posts a form without the token and asserts a 400."],"tags":["antiforgery","aspnetcore","security","csrf","validation"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}