dotnet/aspnetcore · error · AntiforgeryValidationException

The required antiforgery header value

Error message

The required antiforgery header value "{0}" is not present.

What it means

Thrown during antiforgery validation when the application has configured a HeaderName (header-based token lookup) but the incoming request does not have a form content type. Because there is no form, the validator expects the token in the configured header; if the header is also absent, validation fails. This is the AJAX/SPA-style antiforgery path.

Solutions

  1. Have the client send the token in the configured header (default after setting options.HeaderName), e.g. headers['RequestVerificationToken'] = token read from the cookie or a hidden field.
  2. Confirm the request actually reaches the server with the header attached (check browser Network tab and any proxy CORS allowed-headers).
  3. Ensure AntiforgeryOptions.HeaderName matches on both server and client.
  4. If you intend form-based validation instead, leave HeaderName null and post the token as a form field.

Example fix

// before: header configured but not sent
services.AddAntiforgery(o => o.HeaderName = "X-CSRF-TOKEN");
await fetch('/api/data', { method:'POST', headers:{'Content-Type':'application/json'} });

// after: send token in the configured header
const token = getCookie('Antiforgery'); // or read hidden field
await fetch('/api/data', {
  method:'POST',
  headers:{ 'Content-Type':'application/json', 'X-CSRF-TOKEN': token },
  body: JSON.stringify(payload)
});
Defensive patterns

Strategy: validation

Validate before calling

// On the client, before POSTing to a header-protected endpoint:
if (!request.headers.has(options.HeaderName)) { request.headers.set(options.HeaderName, getToken()); }

Try / catch

try { await antiforgery.ValidateRequestAsync(httpContext); }
catch (AntiforgeryValidationException ex) { logger.LogWarning(ex, "Antiforgery header missing"); return Results.BadRequest(); }

Prevention

When it happens

Trigger: AntiforgeryOptions.HeaderName is set (non-null) and ValidateAsync runs on a request whose Content-Type is not a form (e.g. application/json) and whose headers do not carry the configured RequestVerificationToken header.

Common situations: SPA calling a JSON endpoint without attaching the antiforgery header; renaming HeaderName on the server but not the client; sending a header but mis-cased or missing after a reverse proxy strips it; CORS preflight not forwarding the custom header.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/397ce3c0d5fdc471. Report an issue: GitHub.

Appendix: source

Thrown at src/Antiforgery/src/Internal/DefaultAntiforgery.cs:162

        var tokens = await _tokenStore.GetRequestTokensAsync(httpContext);
        if (tokens.CookieToken == null)
        {
            throw new AntiforgeryValidationException(
                Resources.FormatAntiforgery_CookieToken_MustBeProvided(_options.Cookie.Name));
        }

        if (tokens.RequestToken == null)
        {
            if (_options.HeaderName == null)
            {
                var message = Resources.FormatAntiforgery_FormToken_MustBeProvided(_options.FormFieldName);
                throw new AntiforgeryValidationException(message);
            }
            else if (!httpContext.Request.HasFormContentType)
            {
                var message = Resources.FormatAntiforgery_HeaderToken_MustBeProvided(_options.HeaderName);
                throw new AntiforgeryValidationException(message);
            }
            else
            {
                var message = Resources.FormatAntiforgery_RequestToken_MustBeProvided(
                    _options.FormFieldName,
                    _options.HeaderName);
                throw new AntiforgeryValidationException(message);
            }
        }

        ValidateTokens(httpContext, tokens);

        _logger.ValidatedAntiforgeryToken();
    }

    private void ValidateTokens(HttpContext httpContext, AntiforgeryTokenSet antiforgeryTokenSet)
    {
        Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.CookieToken));

View on GitHub (pinned to 3600ca084e)