{"record":{"id":"397ce3c0d5fdc471","repo":"dotnet/aspnetcore","slug":"the-required-antiforgery-header-value-0-is-not","errorCode":null,"errorMessage":"The required antiforgery header value \"{0}\" is not present.","messagePattern":"The required antiforgery header value \"(.+?)\" is not present\\.","errorType":"exception","errorClass":"AntiforgeryValidationException","httpStatus":null,"severity":"error","filePath":"src/Antiforgery/src/Internal/DefaultAntiforgery.cs","lineNumber":162,"sourceCode":"\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();\n    }\n\n    private void ValidateTokens(HttpContext httpContext, AntiforgeryTokenSet antiforgeryTokenSet)\n    {\n        Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.CookieToken));","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Antiforgery/src/Internal/DefaultAntiforgery.cs#L144-L180","documentation":"When HeaderName is configured and the request does not have form content (e.g. a JSON/API request), the request token must arrive via that header. If the header value is absent, AntiforgeryValidationException is thrown. This is the header-based validation path used by SPA/AJAX clients.","triggerScenarios":"HeaderName is set, the request is not form-encoded (JSON body), and the configured header (e.g. RequestVerificationToken) is missing or empty.","commonSituations":"SPA/AJAX/REST clients doing JSON POSTs without sending the antiforgery header; header name mismatch between client and server config; forgot to read the token from the cookie and resend it as a header.","solutions":["Read the antiforgery token from the cookie and send it in the configured header on AJAX requests.","Confirm HeaderName matches between client and server configuration.","Use the standard SPA pattern (fetch the token, set the XSRF header on mutating requests)."],"exampleFix":"// before\nfetch('/api', { method: 'POST', body: JSON, headers: {} });\n\n// after\nfetch('/api', {\n    method: 'POST',\n    headers: { 'RequestVerificationToken': token },\n    body: JSON\n});","handlingStrategy":"try-catch","validationCode":"// C# - confirm the configured header is present for non-form requests\nif (_options.HeaderName != null\n    && !httpContext.Request.HasFormContentType\n    && !httpContext.Request.Headers.TryGetValue(_options.HeaderName, out var h)) {\n    // client must resend the token in the header\n}","typeGuard":null,"tryCatchPattern":"// C#\ntry {\n    await _antiforgery.ValidateRequestAsync(httpContext);\n} catch (AntiforgeryValidationException ex) {\n    // SPA/AJAX: instruct client to send RequestVerificationToken header\n}","preventionTips":["For SPA/AJAX JSON requests, read the token from the cookie and send it in the configured header.","Keep HeaderName consistent between server config and client code.","Use a standard XSRF-TOKEN header pattern for mutating fetch calls."],"tags":["antiforgery","security","csrf","header","spa","aspnetcore"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}