{"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":"validation","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/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Antiforgery/src/Internal/DefaultAntiforgery.cs#L151-L187","documentation":"Thrown when both lookup channels are configured (HeaderName is set) and the request IS a form request, but neither the form field nor the header contains a request token. This is the fallback 'we looked everywhere and found nothing' message after HasFormContentType is true yet form[FormFieldName] and the header are both empty.","triggerScenarios":"AntiforgeryOptions.HeaderName is non-null, the request has a form content type, GetRequestTokensAsync returned a non-null cookie token, but both the form field (FormFieldName) and the header (HeaderName) are null/empty.","commonSituations":"Form posts that were built without the antiforgery tag helper while the server also accepts header-based tokens; a partial view that forgot the hidden field; client middleware that strips unknown form fields; FormFieldName renamed on one side only.","solutions":["Add the antiforgery hidden field to the form (asp-antiforgery form tag helper or @Html.AntiForgeryToken()) so FormFieldName is populated.","Or send the token in the configured HeaderName on the client.","Confirm FormFieldName and HeaderName in AntiforgeryOptions match what the client emits.","Inspect the actual request body/headers in the browser to confirm which channel the client is using and align it with configuration."],"exampleFix":"// before: form tag helper missing\n<form method=\"post\"> ... </form>\n\n// after: tag helper emits token field\n<form method=\"post\" asp-antiforgery=\"true\"> ... </form>","handlingStrategy":"validation","validationCode":"// Client: confirm at least one channel carries a token before submit.\nconst hasForm = !!document.querySelector('input[name=\"__RequestVerificationToken\"]')?.value;\nconst hasHeader = !!headers[configuredHeaderName];\nif (!hasForm && !hasHeader) { /* attach a token */ }","typeGuard":null,"tryCatchPattern":"try { await antiforgery.ValidateRequestAsync(httpContext); }\ncatch (AntiforgeryValidationException) { return Results.BadRequest(); }","preventionTips":["Decide on one channel (form or header) per endpoint family and stick to it.","Audit forms and AJAX calls to ensure the chosen channel always emits the token.","Lock FormFieldName/HeaderName in shared config and reference it from client code."],"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"}