{"record":{"id":"015fc69e41b7cb32","repo":"dotnet/aspnetcore","slug":"the-provided-identity-of-type-0-is-marked-1","errorCode":null,"errorMessage":"The provided identity of type '{0}' is marked {1} = {2} but does not have a value for {3}. By default, the antiforgery system requires that all authenticated identities have a unique {3}. If it is not possible to provide a unique {3} for this identity, consider extending {4} by overriding the {5} or a custom type that can provide some form of unique identifier for the current user.","messagePattern":"The provided identity of type '(.+?)' is marked (.+?) = (.+?) but does not have a value for (.+?)\\. By default, the antiforgery system requires that all authenticated identities have a unique (.+?)\\. If it is not possible to provide a unique (.+?) for this identity, consider extending (.+?) by overriding the (.+?) or a custom type that can provide some form of unique identifier for the current user\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Antiforgery/src/Internal/DefaultAntiforgeryTokenGenerator.cs","lineNumber":86,"sourceCode":"            if (requestToken.ClaimUid == null)\n            {\n                requestToken.Username = authenticatedIdentity.Name;\n            }\n        }\n\n        // populate AdditionalData\n        if (_additionalDataProvider != null)\n        {\n            requestToken.AdditionalData = _additionalDataProvider.GetAdditionalData(httpContext);\n        }\n\n        if (isIdentityAuthenticated\n            && string.IsNullOrEmpty(requestToken.Username)\n            && requestToken.ClaimUid == null\n            && string.IsNullOrEmpty(requestToken.AdditionalData))\n        {\n            // Application says user is authenticated, but we have no identifier for the user.\n            throw new InvalidOperationException(\n                Resources.FormatAntiforgeryTokenValidator_AuthenticatedUserWithoutUsername(\n                    authenticatedIdentity?.GetType() ?? typeof(ClaimsIdentity),\n                    nameof(IIdentity.IsAuthenticated),\n                    \"true\",\n                    nameof(IIdentity.Name),\n                    nameof(IAntiforgeryAdditionalDataProvider),\n                    nameof(DefaultAntiforgeryAdditionalDataProvider)));\n        }\n\n        return requestToken;\n    }\n\n    /// <inheritdoc />\n    public bool IsCookieTokenValid(AntiforgeryToken? cookieToken)\n    {\n        return cookieToken != null && cookieToken.IsCookieToken;\n    }\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Antiforgery/src/Internal/DefaultAntiforgeryTokenGenerator.cs#L68-L104","documentation":"Thrown by GenerateRequestToken (DefaultAntiforgeryTokenGenerator.cs:80-94) when the current user is authenticated but the system cannot derive ANY unique identifier for them — no username (IIdentity.Name is empty), no extractable ClaimUid, and no AdditionalData. The antiforgery system requires every authenticated token to be bound to a unique user identifier to prevent token theft across users; if none is available, it throws InvalidOperationException.","triggerScenarios":"At line 80-84: isIdentityAuthenticated is true, but requestToken.Username is empty, requestToken.ClaimUid is null, and AdditionalData is empty. This happens with authentication schemes that set IsAuthenticated=true but don't populate Name or any claims the ClaimUidExtractor can hash.","commonSituations":"A custom ClaimsIdentity with IsAuthenticated=true but no NameClaimType claim set; authentication middleware that authenticates via a token/header without populating standard claims; an anonymous-converted identity that retains IsAuthenticated; missing NameClaimType configuration in JwtBearer/Cookie auth options.","solutions":["Set the NameClaimType in authentication options so IIdentity.Name resolves (e.g., TokenValidationParameters.NameClaimType = ClaimTypes.Name or a unique claim).","Add a unique claim (sub, nameidentifier, etc.) to the identity so ClaimUidExtractor can derive a ClaimUid.","Implement IAntiforgeryAdditionalDataProvider.GetAdditionalData to return a unique identifier (e.g., session ID, user ID) when standard claims aren't available."],"exampleFix":"// before — authenticated identity with no name claim\nvar identity = new ClaimsIdentity(claims, \"MyScheme\"); // no NameClaimType\n\n// after — set NameClaimType to a unique claim\nvar identity = new ClaimsIdentity(claims, \"MyScheme\",\n    nameType: ClaimTypes.Name, roleType: ClaimTypes.Role);","handlingStrategy":"validation","validationCode":"// Verify the identity has a usable name before generating tokens\nif (httpContext.User?.Identity?.IsAuthenticated == true)\n{\n    if (string.IsNullOrEmpty(httpContext.User.Identity.Name)\n        && !httpContext.User.Claims.Any(c => c.Type == ClaimTypes.NameIdentifier))\n    {\n        throw new InvalidOperationException(\n            \"Authenticated identity has no Name or NameIdentifier claim for antiforgery.\");\n    }\n}","typeGuard":"static bool IdentitySupportsAntiforgery(ClaimsIdentity identity)\n    => identity.IsAuthenticated\n       && (!string.IsNullOrEmpty(identity.Name)\n           || identity.HasClaim(c => c.Type == ClaimTypes.NameIdentifier));","tryCatchPattern":null,"preventionTips":["Always set NameClaimType to a unique claim in custom authentication.","Ensure NameIdentifier/sub claim is present for claims-based identities.","Implement IAntiforgeryAdditionalDataProvider if standard claims aren't available."],"tags":["antiforgery","security","authentication","claims","configuration"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}