dotnet/AspNetCore.Docs · error · Exception

No access token

Error message

No access token

What it means

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.

Source

Thrown at aspnetcore/blazor/security/additional-scenarios.md:137

using System.Net.Http.Headers;
using Microsoft.AspNetCore.Authentication;

public class TokenHandler(IHttpContextAccessor httpContextAccessor) : 
    DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (httpContextAccessor.HttpContext is null)
        {
            throw new Exception("HttpContext not available");
        }

        var accessToken = await httpContextAccessor.HttpContext.GetTokenAsync("access_token");

        if (accessToken is null)
        {
            throw new Exception("No access token");
        }

        request.Headers.Authorization =
            new AuthenticationHeaderValue("Bearer", accessToken);

        return await base.SendAsync(request, cancellationToken);
    }
}
```

> [!NOTE]
> 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.

In 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>.

In 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>.

In `Program.cs`:

View on GitHub (pinned to c67a80103a)

Solutions

  1. Enable SaveTokens = true on the OpenIdConnect/cookie authentication options so tokens are stored in the auth properties.
  2. Verify the requested token name matches what the scheme saves (typically 'access_token').
  3. Implement a token-refresh mechanism so an expired token is renewed before the call.
  4. Guard the caller to avoid issuing the request when the user is unauthenticated.

Example fix

// before
var accessToken = await httpContextAccessor.HttpContext.GetTokenAsync("access_token");
if (accessToken is null)
{
    throw new Exception("No access token");
}

// after — enable token saving + clear error
builder.Services.AddOpenIdConnect(options =>
{
    options.SaveTokens = true;
    // ... other options
});

// in handler
if (string.IsNullOrEmpty(accessToken))
{
    throw new InvalidOperationException(
        "No access token in auth properties. Ensure SaveTokens=true on the OIDC scheme.");
}
Defensive patterns

Strategy: validation

Validate before calling

var token = await httpContext.GetTokenAsync("access_token");
if (string.IsNullOrEmpty(token)) {
    // refresh or redirect to sign-in rather than throw
    return;
}

Type guard

static bool HasAccessToken(HttpContext c) =>
    !string.IsNullOrWhiteSpace(c.GetTokenAsync("access_token").GetAwaiter().GetResult());

Try / catch

try { await client.GetAsync(...); }
catch (Exception ex) when (ex.Message.Contains("No access token"))
{
    logger.LogWarning("Token missing; ensure SaveTokens=true and refresh as needed.");
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dotnet/AspNetCore.Docs@c67a80103a (2026-08-13). Data as JSON: /api/errors/4710c880a8301453. Report an issue: GitHub.