SonarSource/sonarqube · error · BitbucketServerException
Invalid personal access token
Error message
Invalid personal access token
What it means
handleHttpErrorIfAny inspects non-2xx responses. On HTTP 401 (Unauthorized) it throws BitbucketServerException(401, 'Invalid personal access token'), meaning Bitbucket rejected the configured personal access token's credentials. Other codes map to 404 'server unreachable' or a generic IllegalArgumentException.
Source
Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucketserver/BitbucketServerRestClient.java:188
}
protected static void validateResponseBody(boolean isSuccessful, String bodyString) {
if (isSuccessful) {
try {
buildGson().fromJson(bodyString, Object.class);
} catch (JsonParseException e) {
LOG.info(UNEXPECTED_RESPONSE_FROM_BITBUCKET_SERVER + " : [{}]", bodyString);
throw new IllegalArgumentException(UNEXPECTED_RESPONSE_FROM_BITBUCKET_SERVER, e);
}
}
}
protected static void handleHttpErrorIfAny(boolean isSuccessful, int httpCode, String bodyString) {
if (!isSuccessful) {
String errorMessage = getErrorMessage(bodyString);
LOG.info(UNABLE_TO_CONTACT_BITBUCKET_SERVER + ": {} {}", httpCode, errorMessage);
if (httpCode == HTTP_UNAUTHORIZED) {
throw new BitbucketServerException(HTTP_UNAUTHORIZED, "Invalid personal access token");
} else if (httpCode == HTTP_NOT_FOUND) {
throw new BitbucketServerException(HTTP_NOT_FOUND, "Error 404. The requested Bitbucket server is unreachable.");
}
throw new IllegalArgumentException(UNABLE_TO_CONTACT_BITBUCKET_SERVER);
}
}
protected static boolean equals(@Nullable MediaType first, @Nullable MediaType second) {
String s1 = convertMediaTypeToString(first);
String s2 = convertMediaTypeToString(second);
return s1 != null && s1.equals(s2);
}
private static String convertMediaTypeToString(@Nullable MediaType mediaType) {
return Optional.ofNullable(mediaType)
.map(MediaType::toString)
.map(s -> s.toLowerCase(ENGLISH).replace(" ", ""))
.orElse(null);View on GitHub (pinned to 184c821202)
Solutions
- Generate a new personal access token in Bitbucket (with REPO_READ or required project permissions) and update it in the SonarQube ALM integration setting.
- Verify the token belongs to a still-active user on the Bitbucket instance referenced by serverUrl.
- Confirm the token was not truncated/prefixed — paste it again without whitespace.
- Test the token directly: curl -H 'Authorization: Bearer <token>' <serverUrl>/rest/api/1.0/inbox.
Example fix
// before: almSetting pat = expired/revoked token // after: create a new PAT in Bitbucket > Account > Personal access tokens and update the SonarQube ALM setting
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the token before configuring:
curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer <pat>" <serverUrl>/rest/api/1.0/inbox
// expect 200; 401 means the token is invalid/expired/lacks permissions Try / catch
try {
// call client
} catch (BitbucketServerException e) {
if (e.getHttpStatusCode() == 401) {
// prompt admin to refresh the personal access token in ALM settings
}
} Prevention
- Set calendar reminders for PAT expiry; Bitbucket enforces token expiration dates.
- Grant the token's user only the required permissions (REPO_READ) and keep the account active.
- Validate the token with a curl pre-flight check whenever ALM settings change.
- Use a dedicated service account token instead of an individual user's token to survive employee offboarding.
When it happens
Trigger: Calling any Bitbucket REST endpoint when the PAT bound to the ALM setting is revoked, expired, mistyped, lacks the required permissions (e.g. REPO_READ), or belongs to a disabled user — Bitbucket returns 401 and this exception is raised by getBodyString.
Common situations: PAT expired per Bitbucket's token expiry policy; token rotated/revoked after a user left; token pasted with whitespace or from the wrong Bitbucket instance; user account deactivated; token created without repository read permission.
Related errors
- Invalid personal access token
- url must start with http:// or https://
- Unable to contact Bitbucket server
- Unable to contact Bitbucket server, got an unexpected respon
- Unexpected response from Bitbucket server
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/a9981328edb8fc79.
Report an issue: GitHub.