SonarSource/sonarqube · error · IllegalArgumentException
Unable to contact Bitbucket Cloud servers
Error message
Unable to contact Bitbucket Cloud servers
What it means
validateAccessToken() reached a state where it could not produce a specific OAuth error message: either the token endpoint returned a non-success status with a body whose 'error' string was unrecognized and had no parseable error_description, or the response had no usable error body at all. In both cases the client throws IllegalArgumentException('Unable to contact Bitbucket Cloud servers'). It is the generic fallback for any token-exchange failure against Bitbucket Cloud that lacks a diagnosable body, including pure transport IOExceptions.
Source
Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucket/bitbucketcloud/BitbucketCloudRestClient.java:145
Request request = createAccessTokenRequest(clientId, clientSecret);
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
return buildGson().fromJson(response.body().charStream(), Token.class);
}
ErrorDetails errorMsg = getTokenError(response.body(), response.message());
if (errorMsg.body != null) {
LOG.atInfo().log(() -> String.format(BBC_FAIL_WITH_RESPONSE, response.request().url(), response.code(), errorMsg.body));
switch (errorMsg.body) {
case "invalid_grant":
throw new IllegalArgumentException(UNABLE_TO_CONTACT_BBC_SERVERS + ": " + OAUTH_CONSUMER_NOT_PRIVATE);
case "unauthorized_client":
throw new IllegalArgumentException(UNABLE_TO_CONTACT_BBC_SERVERS + ": " + UNAUTHORIZED_CLIENT);
default:
if (errorMsg.parsedErrorMsg != null) {
throw new IllegalArgumentException(ERROR_BBC_SERVERS + ": " + errorMsg.parsedErrorMsg);
} else {
throw new IllegalArgumentException(UNABLE_TO_CONTACT_BBC_SERVERS);
}
}
} else {
LOG.atInfo().log(() -> String.format(BBC_FAIL_WITH_RESPONSE, response.request().url(), response.code(), response.message()));
}
throw new IllegalArgumentException(UNABLE_TO_CONTACT_BBC_SERVERS);
} catch (IOException e) {
LOG.info(String.format(BBC_FAIL_WITH_ERROR, request.url(), e.getMessage()));
throw new IllegalArgumentException(UNABLE_TO_CONTACT_BBC_SERVERS, e);
}
}
public RepositoryList searchRepos(String encodedApiTokenCredentials, String workspace, @Nullable String repoName, Integer page, Integer pageSize) {
String filterQuery = String.format("q=name~\"%s\"", repoName != null ? repoName : "");
HttpUrl url = buildUrl(String.format("/repositories/%s?%s&page=%s&pagelen=%s", workspace, filterQuery, page, pageSize));
return doGetWithApiToken(encodedApiTokenCredentials, url, r -> buildGson().fromJson(r.body().charStream(), RepositoryList.class));
}View on GitHub (pinned to 184c821202)
Solutions
- Test connectivity from the SonarQube server: curl -v https://bitbucket.org/site/oauth2/access_token; fix DNS/firewall/proxy settings (sonar.properties proxy options) accordingly
- Check the server INFO logs for the preceding 'Bitbucket Cloud API call to [...] failed with error: <IOException message>' or 'failed with <code> http code' lines to identify the transport cause
- If a corporate proxy/TLS appliance is present, install its CA into the JVM truststore or bypass it for *.bitbucket.org
- Check the Bitbucket Cloud status page for outages and retry the validation after incidents resolve
- Confirm the configured clientId/secret are non-empty and the consumer is private so the more specific branches (invalid_grant/unauthorized_client) are reachable if applicable
Example fix
// before (proxy blocks egress, IOException -> 'Unable to contact Bitbucket Cloud servers') # sonar.properties (no proxy) // after sonar.proxy.host=proxy.corp.example.com sonar.proxy.port=8080 sonar.proxy.user=svc-sonar sonar.proxy.password=<proxy-password>
Defensive patterns
Strategy: retry
Validate before calling
// Pre-check reachability of the token endpoint before configuring
ProcessResult r = exec("curl -s -o /dev/null -w %{http_code} --max-time 10 https://bitbucket.org/site/oauth2/access_token");
if (!"000".equals(r.output()) && Integer.parseInt(r.output()) >= 500) {
throw new EnvironmentException("bitbucket.org unreachable/unhealthy from this host; fix network before configuring");
} Try / catch
try {
client.validate(clientId, clientSecret, workspace);
} catch (IllegalArgumentException e) {
if ("Unable to contact Bitbucket Cloud servers".equals(e.getMessage())) {
// generic transport/unparsed failure: retry with backoff, then check connectivity
retryWithBackoff(() -> client.validate(clientId, clientSecret, workspace), 3);
}
throw e;
} Prevention
- Ensure the SonarQube host can reach bitbucket.org and api.bitbucket.org (DNS, firewall, proxy config in sonar.properties)
- For corporate TLS inspection, add the proxy CA to the JVM truststore (cacerts)
- Watch the INFO logs — the IOException or HTTP code logged just before this message pinpoints the transport cause
- Check the Bitbucket Cloud status page during incidents rather than troubleshooting credentials
- Retry validation after transient network faults; this message is the expected symptom of pure connectivity loss
When it happens
Trigger: Calling BitbucketCloudRestClient.validate(clientId, clientSecret, workspace) where: (1) the access_token POST returns non-2xx with a body having no parseable error/error_description (HTML error page, blank body, empty response) — line 145 and the trailing line-151 throw after the else branch logs; (2) an IOException occurs during the call (DNS failure, connection reset, TLS error, timeout) — line 155 throw of the same message; (3) response body is not JSON so getTokenError falls back to the raw body string with no parsedErrorMsg.
Common situations: SonarQube server cannot reach bitbucket.org (firewall/proxy/DNS misconfiguration, proxy auth required); corporate TLS interception breaking the handshake; Bitbucket returning an HTML 502/503 error page during incidents; OIDC/proxy stripping the response body; timeouts under load.
Related errors
- Error returned by Bitbucket Cloud: %s
- Unable to contact Bitbucket Cloud servers: Configure the OAu
- Unable to contact Bitbucket Cloud servers: Check your creden
- Error 404. The requested Bitbucket server is unreachable.
- Can not get Bitbucket user profile. HTTP code: %s, response:
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/585e9c4139683e66.
Report an issue: GitHub.