エラーメッセージ
IDX10223: Lifetime validation failed. The token is expired.
別の表記
- Bearer error="invalid_token", error_description="The token expired at '10/20/2026 06:28:30'"
- IDX10222: Lifetime validation failed. The token is not yet valid.
「The token is expired.」以降のテキストには、両方のタイムスタンプがサーバーのカルチャの書式で含まれています。ASP.NET Core の `WWW-Authenticate` の説明(description)は `JwtBearerHandler` が生成します。
Microsoft.IdentityModel.Tokens (.NET) — SecurityTokenExpiredException
このエラーの意味
トークンの `exp` が、現在時刻から `ClockSkew`(デフォルトは 5 分)を引いた時刻より前になっています。署名やほかのクレームは有効な場合もあり、トークンの有効期間が過ぎているだけです。メッセージは「ValidTo (UTC): …, Current time (UTC): …」と続き、ASP.NET Core はクライアントに `error_description="The token expired at '…'"` を返します。IDX10222 はその逆のケースで、`nbf` が未来の時刻になっています。
発生する理由
トークンの有効期間が終了している
よくあるEntra ID のアクセストークンの有効期間はデフォルトで 60〜90 分、ほかのプロバイダーでは 5〜15 分のことがよくあります。`exp` を過ぎても同じトークンを使い続けるクライアントは、きっかりその時刻に失敗します。
許容範囲を超える時刻のずれ
ときどき`ClockSkew` を小さくしていると(たとえば、よく流用される `TimeSpan.Zero`)、発行者と API の間のわずか数秒のずれでも、発行されたばかりのトークンが拒否されます。
トークンライブラリの外でキャッシュされたトークン
ときどきデータベース、静的フィールド、設定ファイルに保存されたトークンは、更新されることがありません。MSAL などのライブラリは、任せれば自動的に更新します。
修正方法
- 1.
時刻のずれの許容値を小さく保つ
許容するずれは分単位ではなく秒単位にとどめ、時計を修正してください。本番環境で `ValidateLifetime = false` を設定してはいけません。
csharp options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = "https://login.example.com/", ValidAudience = "api://orders", ClockSkew = TimeSpan.FromSeconds(30), // default is 5 minutes; lower it, do not raise it to hide expiry }; - 2.
呼び出しのたびにライブラリ経由でトークンを取得する
`AcquireTokenSilent` はキャッシュから有効なトークンを返すか、トークンを更新するため、期限切れはリクエストの前に処理されます。
csharp // Client side (MSAL): ask for a token every time; MSAL returns the cached one or refreshes it. var result = await app.AcquireTokenSilent(scopes, account).ExecuteAsync(); httpClient.DefaultRequestHeaders.Authorization = new("Bearer", result.AccessToken);