justauth/JustAuth · error · AuthException

object.getString("message")

Error message

object.getString("message")

What it means

Second branch of AuthGitlabRequest.checkResponse(): GitLab's REST/user API reports failures with a top-level 'message' key (e.g. {"message":"401 Unauthorized"}), and this branch throws AuthException carrying that message. It typically fires on the userinfo call with a bad or expired access token.

Source

Thrown at src/main/java/me/zhyd/oauth/request/AuthGitlabRequest.java:79

            .blog(object.getString("web_url"))
            .company(object.getString("organization"))
            .location(object.getString("location"))
            .email(object.getString("email"))
            .remark(object.getString("bio"))
            .gender(AuthUserGender.UNKNOWN)
            .token(authToken)
            .source(source.toString())
            .build();
    }

    private void checkResponse(JSONObject object) {
        // oauth/token 验证异常
        if (object.containsKey("error")) {
            throw new AuthException(object.getString("error_description"));
        }
        // user 验证异常
        if (object.containsKey("message")) {
            throw new AuthException(object.getString("message"));
        }
    }

    /**
     * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
     *
     * @param state state 验证授权流程的参数,可以防止csrf
     * @return 返回授权地址
     * @since 1.11.0
     */
    @Override
    public String authorize(String state) {
        return UrlBuilder.fromBaseUrl(super.authorize(state))
            .queryParam("scope", this.getScopes("+", false, AuthScopeUtils.getDefaultScopes(AuthGitlabScope.values())))
            .build();
    }

}

View on GitHub (pinned to 694bbf1b01)

Solutions

  1. Call refresh() with the stored refresh token when the message is 401/403, then retry getUserInfo().
  2. Check that the token in AuthToken came from the same GitLab instance defined in AuthSource.accessToken().
  3. Verify any reverse proxy forwards the Authorization header untouched to GitLab.
  4. Persist refresh tokens at login; GitLab issues them with a longer lifetime than access tokens.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    return gitlabRequest.getUserInfo(token);
} catch (AuthException e) {
    String m = String.valueOf(e.getErrorMsg());
    if (m.contains("401") || m.contains("403")) {
        AuthResponse r = gitlabRequest.refresh(AuthToken.builder().refreshToken(refreshToken).build());
        if (r.ok()) { return gitlabRequest.getUserInfo((AuthToken) r.getData()); }
        return redirectToReauthorize();
    }
    throw e;
}

Prevention

When it happens

Trigger: getUserInfo() with an access token that expired (GitLab tokens default to 2 hours), was revoked, or was issued by a different GitLab instance/application than the one being queried.

Common situations: Session outliving the 2-hour token lifetime without refresh; self-hosted GitLab behind a proxy that strips the Authorization header; or a Personal Access Token mistakenly configured where an OAuth token was expected.

Related errors


AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14). Data as JSON: /api/errors/aaaffd6664bf74b6. Report an issue: GitHub.