theonedev/onedev · error · AuthenticationException
OIDC error: Inconsistent sub in ID token and userinfo
Error message
OIDC error: Inconsistent sub in ID token and userinfo
What it means
Thrown by OpenIdConnector.processTokenResponse after fetching the userinfo endpoint: the 'sub' (subject) returned by userinfo does not match the 'sub' claim of the ID token. OIDC requires these to be identical; a mismatch signals a misconfigured or compromised provider setup, so authentication is aborted.
Source
Thrown at server-plugin/server-plugin-sso-openid/src/main/java/io/onedev/server/plugin/sso/openid/OpenIdConnector.java:267
groups = null;
} else {
groups = null;
}
var accessToken = tokenResponse.getOIDCTokens().getBearerAccessToken();
if (email == null || userName == null || fullName == null
|| getGroupsClaim() != null && groups == null) {
UserInfoRequest userInfoRequest = new UserInfoRequest(
new URI(getCachedProviderMetadata().getUserInfoEndpoint()), accessToken);
var httpRequest = userInfoRequest.toHTTPRequest();
httpRequest.setSSLSocketFactory(TrustCertsSSLSocketFactory.getDefault());
var httpResponse = httpRequest.send();
if (httpResponse.getStatusCode() == HTTPResponse.SC_OK) {
JSONObject json = httpResponse.getBodyAsJSONObject();
if (!subject.equals(json.get("sub")))
throw new AuthenticationException(_T("OIDC error: Inconsistent sub in ID token and userinfo"));
if (email == null) {
email = getStringValue(json.get("email"));
emailVerified = getBooleanValue(json.get("email_verified"));
if (emailVerified == null)
emailVerified = getBooleanValue(json.get("emailVerified"));
if (emailVerified != null && !emailVerified)
email = null;
}
if (userName == null)
userName = getStringValue(json.get("preferred_username"));
if (fullName == null)
fullName = getStringValue(json.get("name"));
if (getGroupsClaim() != null && groups == null) {
var jsonArray = (JSONArray) json.get(getGroupsClaim());View on GitHub (pinned to d44925c47c)
Solutions
- Verify the connector's userinfo/discovery configuration points to the same provider and realm that issued the ID token.
- Update or fix the identity provider so userinfo returns the same sub as the ID token (same realm, no rewriting proxy).
- Check for intermediary proxies/gateways altering the userinfo response body.
- Compare sub value types (string vs numeric) returned by the provider and update provider firmware/version if it emits a typed mismatch.
Example fix
// before: token from realm A, userinfo from realm B wellKnownConfiguration: "https://sso.example.com/realms/old/.well-known/openid-configuration" // after wellKnownConfiguration: "https://sso.example.com/realms/current/.well-known/openid-configuration"
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check userinfo before wiring the connector: // GET userinfo endpoint with a test token; assert response JSON 'sub' equals the ID token's sub.
Try / catch
try {
auth = connector.handleAuthResponse(...);
} catch (AuthenticationException e) {
if (e.getMessage().contains("Inconsistent sub")) {
// verify token issuer realm and userinfo endpoint alignment, then retry
}
} Prevention
- Ensure discovery/userinfo and token issuance come from the same realm/provider.
- Remove or fix proxies that rewrite userinfo responses.
- Test the full login with a real account after any provider configuration change.
- Keep the identity provider updated to avoid sub type/format bugs.
When it happens
Trigger: The connector calls the userinfo endpoint (over an SSL connection using TrustCertsSSLSocketFactory) and compares json.get("sub") with the ID token subject; the values differ — typically when a proxy/gateway or mismatched client configuration returns a different user, or token/userinfo come from different realms/issuers.
Common situations: Identity provider behind a gateway that rewrites or substitutes responses; userinfo URL pointing to a different realm/environment than the token issuer; multiple identity providers (e.g. Keycloak realms) mixed in connector settings; provider bug where userinfo sub is stored as number vs string type difference.
Related errors
- Inconsistent issuer in provider metadata and ID token
- Invalid issue date of ID token
- 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/71caae2bb8fdf181.
Report an issue: GitHub.