theonedev/onedev · error · AuthenticationException
Inconsistent issuer in provider metadata and ID token
Error message
Inconsistent issuer in provider metadata and ID token
What it means
Thrown by OpenIdConnector.processTokenResponse when the 'iss' (issuer) claim of the received ID token does not equal the issuer advertised in the provider's discovery metadata (getCachedProviderMetadata().getIssuer()). This per OIDC spec validation prevents token substitution or misconfigured provider endpoints from yielding tokens minted by a different issuer.
Source
Thrown at server-plugin/server-plugin-sso-openid/src/main/java/io/onedev/server/plugin/sso/openid/OpenIdConnector.java:220
return (Boolean)jsonValue;
} else if (jsonValue instanceof JSONArray) {
JSONArray jsonArray = (JSONArray) jsonValue;
if (!jsonArray.isEmpty())
return (Boolean) jsonArray.iterator().next();
else
return null;
} else {
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)View on GitHub (pinned to d44925c47c)
Solutions
- Make the connector's provider metadata (well-known/discovery) URL exactly match the issuer URL in the token (scheme, host, port, path).
- Fix reverse-proxy configuration so the provider emits its public (external) URL as issuer and OneDev uses that same URL.
- Avoid mixing http/https or localhost vs FQDN between discovery URL and the provider's real issuer.
- Update the provider (e.g. Keycloak realm URL) config in the OneDev SSO connector after any provider URL change.
Example fix
// before: discovery via internal host wellKnownConfiguration: "http://keycloak.internal:8080/realms/myrealm/.well-known/openid-configuration" // after: use the same public issuer the token carries wellKnownConfiguration: "https://sso.example.com/realms/myrealm/.well-known/openid-configuration"
Defensive patterns
Strategy: validation
Validate before calling
// Before configuring, fetch discovery metadata and compare with expected issuer:
var meta = HttpResource.retrieve(wellKnownUrl);
System.out.println(meta.toJSONObject().get("issuer")); // must match token 'iss' exactly Try / catch
try {
auth = connector.handleAuthResponse(...);
} catch (AuthenticationException e) {
if (e.getMessage().contains("Inconsistent issuer")) {
// fix provider metadata URL to match the token issuer, then retry
}
} Prevention
- Use the provider's public issuer URL (scheme/host/path) verbatim in connector settings.
- After changing provider URLs (http->https, new domain), update the connector.
- Fix reverse proxies so the provider advertises its external URL as issuer.
- Test with a discovery fetch and compare issuer to a decoded ID token.
When it happens
Trigger: After exchanging the authorization code, the ID token's iss claim differs from the well-known configuration issuer — e.g. connector points at a discovery URL whose metadata issuer uses a different scheme/host/path than the token endpoint actually issuing tokens.
Common situations: Provider behind a proxy reached via different hostnames (internal vs external URL); http vs https mismatch in the well-known URL; issuer with/without trailing path (realm name) misconfigured; switching from HTTP to HTTPS on the identity provider without updating connector settings; older provider versions omitting the issuer check nuances.
Related errors
- Invalid issue date of ID token
- OIDC error: Inconsistent sub in ID token and userinfo
- Unsolicited OIDC authentication response
- Unsolicited OIDC authentication response
- ID token was expired
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/f9930dae3e79325e.
Report an issue: GitHub.