justauth/JustAuth · error · AuthException
errorDescription
Error message
errorDescription
What it means
AuthGithubRequest.checkResponse(boolean error, String errorDescription) is called with a flag derived from the response (presence of an 'error' key) and the error_description string; when the flag is true it throws AuthException with just that description. GitHub's OAuth failures return {error, error_description, error_uri}.
Source
Thrown at src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java:79
.rawUserInfo(object)
.uuid(object.getString("id"))
.username(object.getString("login"))
.avatar(object.getString("avatar_url"))
.blog(object.getString("blog"))
.nickname(object.getString("name"))
.company(object.getString("company"))
.location(object.getString("location"))
.email(object.getString("email"))
.remark(object.getString("bio"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source.toString())
.build();
}
private void checkResponse(boolean error, String errorDescription) {
if (error) {
throw new AuthException(errorDescription);
}
}
/**
* 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
*
* @param state state 验证授权流程的参数,可以防止csrf
* @return 返回授权地址
*/
@Override
public String authorize(String state) {
return UrlBuilder.fromBaseUrl(super.authorize(state))
.queryParam("scope", this.getScopes(" ", true, AuthScopeUtils.getDefaultScopes(AuthGithubScope.values())))
.build();
}
}
View on GitHub (pinned to 694bbf1b01)
Solutions
- Exchange the code promptly (GitHub codes expire in ~10 minutes) and only once - reload of the callback page is the classic trigger for bad_verification_code.
- Verify client_id/client_secret pair against the GitHub Developer settings OAuth Apps page.
- Ensure redirect_uri matches exactly what is registered, including scheme and trailing slash.
- For 'bad expiration' or token-invalid errors, refresh or re-authorize instead of retrying the same token.
Defensive patterns
Strategy: try-catch
Try / catch
try {
return githubRequest.getAccessToken(callback);
} catch (AuthException e) {
String m = String.valueOf(e.getErrorMsg());
if (m.contains("bad_verification_code")) {
return AuthResponse.builder().msg("GitHub code expired or already used - restart the login flow").build();
}
throw e;
} Prevention
- Exchange the GitHub code within its ~10-minute window - process callbacks synchronously, do not queue them.
- Prevent double exchange: the authorize page's redirect should never be refreshable (use redirects, POST-then-redirect).
- Keep the GitHub OAuth app's callback URL and secret in sync with deployed config.
When it happens
Trigger: Token exchange with a wrong client_secret or mismatched redirect_uri, or redeeming a code twice - GitHub responds with error='bad_verification_code' and the description becomes the exception message; also fires on the user endpoint for an expired token.
Common situations: The 10-minute validity window of the GitHub code expiring before exchange (slow handler, queue lag); client secret rotated by a GitHub App; redirect_uri http/https mismatch with the GitHub OAuth app settings.
Related errors
- JSONObject.toJSONString(response)
- object.getString("error") + ":" + object.getString("message"
- object.getString("error_description")
- object.getString("error_description") / object.getString("er
- object.getString("msg")
AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14).
Data as JSON: /api/errors/f3f81a3609d8eb38.
Report an issue: GitHub.