The Error
API returns 401 with this in logs:
IDX10501: Signature validation failed. Unable to match key.
kid: 'ABC123'.
Quick Fix - 2 Minutes
Your API can't find the signing key from Auth0/Azure AD. Check 3 things:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://login.microsoftonline.com/your-tenant-id/v2.0";
options.Audience = "api://your-client-id";
// Add this for debugging:
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "https://login.microsoftonline.com/your-tenant-id/v2.0"
};
});
Why This Happens
JWT tokens are signed by your identity provider. Your API downloads public keys from Authority + /.well-known/openid-configuration. If Authority is wrong, or clock skew > 5 min, validation fails.
Step-by-Step Debug
- Check Authority: Paste
https://your-authority/.well-known/openid-configurationin browser. Should return JSON - Check Audience: Must exactly match
audclaim in token. Use jwt.io to decode - Check ClockSkew: Add
ClockSkew = TimeSpan.Zeroif server time is off - Check kid: The
kidin error must exist injwks_urifrom step 1
Real-World Scenario: Works Locally, Fails on Azure App Service
#1 most common prod issue. Token validates in VS, 401 on Azure:
// Program.cs - Add this to fix Azure clock skew + key caching
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = builder.Configuration["AzureAd:Authority"];
options.Audience = builder.Configuration["AzureAd:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(5), // Azure time can drift
RequireSignedTokens = true
};
// Force refresh signing keys every 24h - Azure AD rotates keys
options.BackchannelTimeout = TimeSpan.FromSeconds(60);
options.RefreshOnIssuerKeyNotFound = true;
options.AutomaticRefreshInterval = TimeSpan.FromHours(24);
});
// For debugging only - shows exact failure reason
builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>();
logger.LogError(context.Exception, "JWT validation failed");
return Task.CompletedTask;
}
};
});
3 Azure-specific fixes:
- ClockSkew: Azure VMs drift 2-3 minutes. Default 5min tolerance helps.
- RefreshOnIssuerKeyNotFound: Azure AD rotates keys monthly. Without this, you get IDX10501 until app restart.
- HTTPS required: Azure App Service terminates SSL. If you use HTTP internally,
RequireHttpsMetadata = falsein dev only.
Related Fixes You Should Know
JWT 401 usually cascades into these:
- CORS With Credentials - JWT works in Postman but fails from React/Angular. Missing
WithCredentials()+Authorizationheader in CORS policy. - JWT Token Expired 401 - Token is valid but expired. Add refresh token flow or increase
accessTokenLifetimein identity provider. - HTTPS Redirect Loop - App Service + JWT breaks because middleware redirects HTTP→HTTPS before auth. Causes infinite loop.
- Azure KeyVault 401 Unauthorized - Same pattern: managed identity + wrong audience. Fix Audience to match KeyVault resource.
FAQ
Q: What does "kid" mean in IDX10501 error?
kid = Key ID. JWT header says "signed with key ABC123". Your API downloads all public keys from jwks_uri. If ABC123 isn't in that list, signature fails. Usually means wrong Authority or cached keys.
Q: Why does JWT work locally but fail in Docker/Kubernetes?
Container time is wrong, or container can't reach Authority URL. Check: 1. date inside container, 2. curl https://login.microsoftonline.com/.well-known/openid-configuration from container. Add ClockSkew = TimeSpan.FromMinutes(5) for time drift.
Common Scenarios
- Wrong Authority: Using v1 endpoint but token is v2, or vice versa
- Staging vs Prod: Different Azure AD tenants have different keys
- Cached keys: Restart app if identity provider rotated keys
No comments yet. Be the first to share your thoughts!