dotnet/aspnetcore · error · AntiforgeryValidationException

The provided antiforgery token was meant for a different cla

Error message

The provided antiforgery token was meant for a different claims-based user than the current user.

What it means

Thrown during TryValidateTokenSet when the request token carries a ClaimUid (a claims-based identifier) that does not match the ClaimUid derived from the current user's claims. Unlike username-based binding, claims-based binding hashes the user's claim set; a mismatch indicates the claim set changed or belongs to a different user. Produced by Resources.AntiforgeryToken_ClaimUidMismatch at DefaultAntiforgeryTokenGenerator.cs:181.

Source

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

        // Extract cookie & request tokens
        AntiforgeryToken deserializedCookieToken;
        AntiforgeryToken deserializedRequestToken;

        DeserializeTokens(
            httpContext,
            antiforgeryTokenSet,
            out deserializedCookieToken,
            out deserializedRequestToken);

        // Validate
        if (!_tokenGenerator.TryValidateTokenSet(
            httpContext,
            deserializedCookieToken,
            deserializedRequestToken,
            out var message))
        {
            throw new AntiforgeryValidationException(message);
        }
    }

    /// <inheritdoc />
    public void SetCookieTokenAndHeader(HttpContext httpContext)
    {
        ArgumentNullException.ThrowIfNull(httpContext);

        CheckSSLConfig(httpContext);

        var antiforgeryFeature = GetCookieTokens(httpContext);
        if (!antiforgeryFeature.HaveStoredNewCookieToken && antiforgeryFeature.NewCookieToken != null)
        {
            if (antiforgeryFeature.NewCookieTokenString == null)
            {
                antiforgeryFeature.NewCookieTokenString =
                    _tokenSerializer.Serialize(antiforgeryFeature.NewCookieToken);
            }

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Regenerate the antiforgery token after claims change (e.g., after role assignment) by calling GetAndStoreTokens and reloading the page.
  2. Ensure claim extraction is deterministic — verify ClaimUidExtractor uses stable, consistent claim types across all requests.
  3. If claims legitimately change often, consider falling back to username-based validation by not populating extractable claims, or implement IAntiforgeryAdditionalDataProvider.
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    await _antiforgery.ValidateRequestAsync(HttpContext);
}
catch (AntiforgeryValidationException ex)
{
    _logger.LogWarning("ClaimUid mismatch: {Msg}", ex.Message);
    return BadRequest("Session changed — please reload.");
}

Prevention

When it happens

Trigger: The current user is authenticated with claims (so TryExtractClaimUidBytes succeeds) but the computed ClaimUid differs from the ClaimUid embedded in the request token. Detected via AreIdenticalClaimUids returning false at line 177.

Common situations: User's claims or roles changed after the token was minted (e.g., admin role granted/revoked); token generated by a different claims configuration; custom claim types that vary between requests; upgrading authentication schemes so claim extraction logic changed.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/9ae04ecc3d142912. Report an issue: GitHub.