{"record":{"id":"4710c880a8301453","repo":"dotnet/AspNetCore.Docs","slug":"no-access-token","errorCode":null,"errorMessage":"No access token","messagePattern":"No access token","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"aspnetcore/blazor/security/additional-scenarios.md","lineNumber":137,"sourceCode":"using System.Net.Http.Headers;\nusing Microsoft.AspNetCore.Authentication;\n\npublic class TokenHandler(IHttpContextAccessor httpContextAccessor) : \n    DelegatingHandler\n{\n    protected override async Task<HttpResponseMessage> SendAsync(\n        HttpRequestMessage request, CancellationToken cancellationToken)\n    {\n        if (httpContextAccessor.HttpContext is null)\n        {\n            throw new Exception(\"HttpContext not available\");\n        }\n\n        var accessToken = await httpContextAccessor.HttpContext.GetTokenAsync(\"access_token\");\n\n        if (accessToken is null)\n        {\n            throw new Exception(\"No access token\");\n        }\n\n        request.Headers.Authorization =\n            new AuthenticationHeaderValue(\"Bearer\", accessToken);\n\n        return await base.SendAsync(request, cancellationToken);\n    }\n}\n```\n\n> [!NOTE]\n> For guidance on how to access an `AuthenticationStateProvider` from a `DelegatingHandler`, see the [Access `AuthenticationStateProvider` in outgoing request middleware](#access-authenticationstateprovider-in-outgoing-request-middleware) section.\n\nIn the project's `Program` file, the token handler (`TokenHandler`) is registered as a scoped service and specified as a [named HTTP client's](xref:blazor/call-web-api#named-httpclient-with-ihttpclientfactory) message handler with <xref:Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.AddHttpMessageHandler%2A>.\n\nIn the following example, the `{HTTP CLIENT NAME}` placeholder is the name of the <xref:System.Net.Http.HttpClient>, and the `{BASE ADDRESS}` placeholder is the web API's base address URI. For more information on <xref:Microsoft.Extensions.DependencyInjection.HttpServiceCollectionExtensions.AddHttpContextAccessor%2A>, see <xref:blazor/components/httpcontext>.\n\nIn `Program.cs`:","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/dotnet/AspNetCore.Docs/blob/c67a80103a1a74db20784debd919c7fdda96c510/aspnetcore/blazor/security/additional-scenarios.md#L119-L155","documentation":"Exception(\"No access token\") thrown by TokenHandler.SendAsync after GetTokenAsync(\"access_token\") returns null. The handler cannot attach a Bearer Authorization header without a token, so it refuses to forward the request. Indicates the user's authentication properties did not include a saveable access_token.","triggerScenarios":"The OIDC/cookie auth scheme did not save the access_token (SaveTokens=true not set, or token names differ); the user is authenticated but the token expired/removed; GetTokenAsync was called with the wrong token name; the authentication properties lack token storage.","commonSituations":"OpenIdConnect options missing SaveTokens = true; external OIDC provider using a non-standard token name; cookie auth without sliding refresh; user signed out between token capture and the HTTP call.","solutions":["Enable SaveTokens = true on the OpenIdConnect/cookie authentication options so tokens are stored in the auth properties.","Verify the requested token name matches what the scheme saves (typically 'access_token').","Implement a token-refresh mechanism so an expired token is renewed before the call.","Guard the caller to avoid issuing the request when the user is unauthenticated."],"exampleFix":"// before\nvar accessToken = await httpContextAccessor.HttpContext.GetTokenAsync(\"access_token\");\nif (accessToken is null)\n{\n    throw new Exception(\"No access token\");\n}\n\n// after — enable token saving + clear error\nbuilder.Services.AddOpenIdConnect(options =>\n{\n    options.SaveTokens = true;\n    // ... other options\n});\n\n// in handler\nif (string.IsNullOrEmpty(accessToken))\n{\n    throw new InvalidOperationException(\n        \"No access token in auth properties. Ensure SaveTokens=true on the OIDC scheme.\");\n}","handlingStrategy":"validation","validationCode":"var token = await httpContext.GetTokenAsync(\"access_token\");\nif (string.IsNullOrEmpty(token)) {\n    // refresh or redirect to sign-in rather than throw\n    return;\n}","typeGuard":"static bool HasAccessToken(HttpContext c) =>\n    !string.IsNullOrWhiteSpace(c.GetTokenAsync(\"access_token\").GetAwaiter().GetResult());","tryCatchPattern":"try { await client.GetAsync(...); }\ncatch (Exception ex) when (ex.Message.Contains(\"No access token\"))\n{\n    logger.LogWarning(\"Token missing; ensure SaveTokens=true and refresh as needed.\");\n}","preventionTips":["Set SaveTokens = true on the OIDC scheme.","Verify the token name matches what the scheme saves.","Implement refresh-token handling to renew expired tokens.","Block calls when the user is unauthenticated."],"tags":["blazor","tokens","authentication","oidc","delegatinghandler"],"backgroundTag":null,"analyzedSha":"c67a80103a1a74db20784debd919c7fdda96c510","analyzedAt":"2026-08-13T17:46:11.763Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}