theonedev/onedev · error · AuthenticationException
ID token was expired
Error message
ID token was expired
What it means
Thrown by OpenIdConnector.processTokenResponse when the ID token's exp (expiration) claim exists and is already in the past at validation time. The connector rejects expired tokens rather than trusting an authentication that is no longer valid.
Source
Thrown at server-plugin/server-plugin-sso-openid/src/main/java/io/onedev/server/plugin/sso/openid/OpenIdConnector.java:228
return null;
}
}
protected SsoAuthenticated processTokenResponse(OIDCTokenResponse tokenResponse) {
try {
JWT idToken = tokenResponse.getOIDCTokens().getIDToken();
JWTClaimsSet claims = idToken.getJWTClaimsSet();
if (!claims.getIssuer().equals(getCachedProviderMetadata().getIssuer()))
throw new AuthenticationException(_T("Inconsistent issuer in provider metadata and ID token"));
DateTime now = new DateTime();
if (claims.getIssueTime() != null && claims.getIssueTime().after(now.plusSeconds(10).toDate()))
throw new AuthenticationException(_T("Invalid issue date of ID token"));
if (claims.getExpirationTime() != null && now.toDate().after(claims.getExpirationTime()))
throw new AuthenticationException(_T("ID token was expired"));
Session.get().setAttribute(SESSION_ATTR_ID_TOKEN, idToken.serialize());
String subject = claims.getSubject();
String email = StringUtils.trimToNull(claims.getStringClaim("email"));
Boolean emailVerified = claims.getBooleanClaim("email_verified");
if (emailVerified == null)
emailVerified = claims.getBooleanClaim("emailVerified");
if (emailVerified != null && !emailVerified)
email = null;
String userName = StringUtils.trimToNull(claims.getStringClaim("preferred_username"));
String fullName = StringUtils.trimToNull(claims.getStringClaim("name"));
List<String> groups;
if (getGroupsClaim() != null) {
var groupsArray = claims.getStringArrayClaim(getGroupsClaim());
if (groupsArray != null)View on GitHub (pinned to d44925c47c)
Solutions
- Synchronize the OneDev server clock with NTP, then retry the login.
- Retry the SSO login to obtain a fresh token promptly after redirect.
- Increase the ID token lifetime on the identity provider if it expires before the exchange completes.
- Investigate slow token endpoint responses (network latency to the provider) that delay validation past exp.
Defensive patterns
Strategy: retry
Try / catch
try {
auth = connector.handleAuthResponse(...);
} catch (AuthenticationException e) {
if (e.getMessage().contains("ID token was expired")) {
// sync clocks if skewed, then retry login to get a fresh token
}
} Prevention
- Keep server clocks NTP-synchronized.
- Set a reasonable ID token lifetime on the provider (not a few seconds).
- Complete the OAuth redirect promptly; investigate slow token endpoint calls.
- Avoid replaying old authorization codes.
When it happens
Trigger: The token response reaches processTokenResponse after the ID token's exp time has passed — long delay between the provider issuing the token and the code-exchange/validation step, or a token with a very short expiry combined with clock skew.
Common situations: Severe OneDev server clock skew making a valid token look expired; extremely short token lifetime configured on the provider; slow networks or stalled token endpoint calls exceeding token TTL; reusing an old authorization code whose token expired.
Related errors
- Invalid issue date of ID token
- Unsolicited OIDC authentication response
- Unsolicited OIDC authentication response
- Inconsistent issuer in provider metadata and ID token
- OIDC error: Inconsistent sub in ID token and userinfo
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/226609412e8d232e.
Report an issue: GitHub.