justauth/JustAuth · error · AuthException
${error_description}
Error message
${error_description} What it means
AbstractAuthMicrosoftRequest.checkResponse inspects the Microsoft/Azure AD token response and, if it contains an 'error' key, throws AuthException with the response's error_description. This is Microsoft OAuth passing back a real protocol error: invalid_grant (bad/expired code), invalid_client (wrong client id/secret), or invalid_request (malformed parameters).
Source
Thrown at src/main/java/me/zhyd/oauth/request/AbstractAuthMicrosoftRequest.java:78
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
.expireIn(accessTokenObject.getIntValue("expires_in"))
.scope(accessTokenObject.getString("scope"))
.tokenType(accessTokenObject.getString("token_type"))
.refreshToken(accessTokenObject.getString("refresh_token"))
.build();
}
/**
* 检查响应内容是否正确
*
* @param object 请求响应内容
*/
private void checkResponse(JSONObject object) {
if (object.containsKey("error")) {
throw new AuthException(object.getString("error_description"));
}
}
@Override
public AuthUser getUserInfo(AuthToken authToken) {
String token = authToken.getAccessToken();
String tokenType = authToken.getTokenType();
String jwt = tokenType + " " + token;
HttpHeader httpHeader = new HttpHeader();
httpHeader.add("Authorization", jwt);
String userInfo = new HttpUtils(config.getHttpConfig()).get(userInfoUrl(authToken), null, httpHeader, false).getBody();
JSONObject object = JSONObject.parseObject(userInfo);
this.checkResponse(object);
return AuthUser.builder()
.rawUserInfo(object)
.uuid(object.getString("id"))View on GitHub (pinned to 694bbf1b01)
Solutions
- Read the error_description — it contains the AADSTS code; look it up in Microsoft's error reference for the precise cause.
- For invalid_client: re-copy clientId/clientSecret from the Azure app registration (Certificates & secrets) and restart/rebuild the request with the new AuthConfig.
- For invalid_grant: never reuse an auth code or refresh token; send the user back through authorize(). Ensure redirectUri is byte-identical in both steps and included in the app registration's redirect URIs.
- When refreshing, request scope offline_access during authorization or refresh will fail.
Example fix
// before AuthConfig cfg = AuthConfig.builder().clientId(id).clientSecret(staleSecret).redirectUri(uri).build(); // invalid_client // after AuthConfig cfg = AuthConfig.builder().clientId(id).clientSecret(currentSecret).redirectUri(uri).build(); // and ensure the same redirectUri is registered in Azure: App registrations -> Authentication -> Redirect URIs
Defensive patterns
Strategy: try-catch
Validate before calling
// before token exchange: ensure code present and single-use
if (StringUtils.isEmpty(callback.getCode())) throw new IllegalArgumentException("missing code");
if (codeStore.consumeIfAbsent(callback.getCode()) == null) throw new IllegalStateException("code already used"); Try / catch
try { return request.getAccessToken(cb); } catch (AuthException e) { if (e.getMessage() != null && e.getMessage().contains("invalid_grant")) { return restartAuthorize(); } throw e; } Prevention
- Never reuse an auth code — mark it consumed on first exchange.
- Keep clientId/clientSecret in a secret manager and rotate before expiry.
- Make redirectUri byte-identical between authorize and token calls and register it in Azure.
- Request scope offline_access when you need refresh tokens.
When it happens
Trigger: Calling getAccessToken with a consumed or expired authorization code (invalid_grant); client secret mismatch or unexpired-credential rotation (invalid_client); redirect_uri differing between authorize and token requests; missing the offline_access/scope needed for a refresh_token when refreshing.
Common situations: Azure AD app secrets expire (~1-2 years) and get rotated but the config is not updated; users retry the callback URL so the auth_code is reused; tenant misconfiguration (common vs organizations endpoint) causing AADSTS errors; clock skew causing code expiry.
Related errors
AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14).
Data as JSON: /api/errors/01c16ae27beef32b.
Report an issue: GitHub.