{"record":{"id":"3e7a5fb282b43983","repo":"SonarSource/sonarqube","slug":"error-returned-by-bitbucket-cloud","errorCode":null,"errorMessage":"Error returned by Bitbucket Cloud","messagePattern":"Error returned by Bitbucket Cloud","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucket/bitbucketcloud/BitbucketCloudRestClient.java","lineNumber":233,"sourceCode":"  protected <G> G doGetWithApiToken(String encodedApiTokenCredentials, HttpUrl url, Function<Response, G> handler) {\n    // Bitbucket Cloud expects API tokens to be transported as Basic authorization with base64(email:apiToken).\n    Request request = prepareRequestWithAuthorizationHeader(\"Basic \" + encodedApiTokenCredentials, GET, url, null);\n    try {\n      return doCall(request, handler);\n    } catch (BitbucketCloudException e) {\n      throw new IllegalStateException(e.getMessage(), e);\n    }\n  }\n\n  protected <G> G doCall(Request request, Function<Response, G> handler) {\n    try (Response response = client.newCall(request).execute()) {\n      if (!response.isSuccessful()) {\n        handleError(response);\n      }\n      return handler.apply(response);\n    } catch (IOException e) {\n      LOG.info(ERROR_BBC_SERVERS + \": {}\", e.getMessage());\n      throw new IllegalStateException(ERROR_BBC_SERVERS, e);\n    }\n  }\n\n  private static void handleError(Response response) throws IOException {\n    ErrorDetails error = getError(response.body(), response.message());\n    int statusCode = response.code();\n    LOG.atInfo().log(() -> String.format(BBC_FAIL_WITH_RESPONSE, response.request().url(), statusCode, error.body));\n    String errorMessage;\n    if (error.parsedErrorMsg != null) {\n      errorMessage = ERROR_BBC_SERVERS + \": \" + error.parsedErrorMsg + \" [HTTP \" + statusCode + \"]\";\n    } else {\n      errorMessage = UNABLE_TO_CONTACT_BBC_SERVERS + \" [HTTP \" + statusCode + \"]\";\n    }\n    throw new BitbucketCloudException(errorMessage, statusCode);\n  }\n\n  private static ErrorDetails getError(@Nullable ResponseBody body, @Nullable String fallbackMessage) throws IOException {\n    return getErrorDetails(body, fallbackMessage, s -> {","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucket/bitbucketcloud/BitbucketCloudRestClient.java#L215-L251","documentation":"doCall executes the HTTP request and, when the call itself throws an IOException (no HTTP response at all: DNS failure, timeout, connection reset, TLS error), logs and rethrows it as IllegalStateException(\"Error returned by Bitbucket Cloud\", e). Despite the wording, this is not an error returned by Bitbucket — it means the request never completed and no server response was received. Successful responses with non-2xx codes are instead routed to handleError (error 24).","triggerScenarios":"Thrown from doCall, called by createAccessToken, doGet and doGetWithApiToken, whenever client.newCall(request).execute() throws IOException while calling api.bitbucket.org or the OAuth token endpoint: unknown host, connect/read timeout, connection reset, or SSL handshake failure.","commonSituations":"SonarQube server has no egress to api.bitbucket.org (firewall, air-gapped installation); proxy not configured for the JVM; DNS outage; TLS-intercepting proxy with untrusted certificates; Bitbucket Cloud returning a connection-level failure during an outage; response read interrupted by socket timeout on large repository listings.","solutions":["Look at the IllegalStateException's cause (IOException) or the INFO log 'Error returned by Bitbucket Cloud: <message>' to identify the exact transport failure.","Test connectivity from the SonarQube host: curl -v https://api.bitbucket.org/2.0/repositories/<workspace>.","Configure JVM proxy settings (-Dhttps.proxyHost/-Dhttps.proxyPort/-Dhttps.nonProxyHosts) if a proxy is mandatory in your environment, then restart.","If the failure is TLS-related, add the corporate CA certificate to the JVM truststore (cacerts).","If it is a read timeout on large paginated responses, increase the OkHttp timeouts of the bitBucketCloudHttpClient bean and/or reduce page sizes."],"exampleFix":"// before: no proxy configured, execute() throws IOException\nRequest r = new Request.Builder().url(\"https://api.bitbucket.org/2.0/repositories/ws\").build();\n// after: build the injected OkHttpClient with a proxy so execute() succeeds\nOkHttpClient c = base.newBuilder()\n  .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(\"proxy.corp\", 8080)))\n  .connectTimeout(30, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS)\n  .build();","handlingStrategy":"retry","validationCode":"// Reachability probe before first use of the client:\nstatic boolean canReachBitbucketApi() {\n  try {\n    HttpURLConnection c = (HttpURLConnection) URI.create(\"https://api.bitbucket.org/2.0/\").toURL().openConnection();\n    c.setConnectTimeout(5000);\n    c.setReadTimeout(10000);\n    return c.getResponseCode() > 0;\n  } catch (IOException e) {\n    return false;\n  }\n}\n// If false, fix DNS/proxy/firewall before calling createAccessToken/doGet/doGetWithApiToken.","typeGuard":null,"tryCatchPattern":"// Since this is a transport-level failure, retry with backoff and preserve the cause:\nRuntimeException last = null;\nfor (int attempt = 1; attempt <= 3; attempt++) {\n  try {\n    return doCallSomething();\n  } catch (IllegalStateException e) {\n    if (\"Error returned by Bitbucket Cloud\".equals(e.getMessage()) && e.getCause() instanceof IOException) {\n      last = e;\n      sleepBackoff(attempt); // e.g. 1s, 2s, 4s\n      continue;\n    }\n    throw e; // parsed HTTP error — not retryable at transport level\n  }\n}\nthrow last;","preventionTips":["Ensure the SonarQube host has reliable egress to api.bitbucket.org:443; test with curl before rollout.","Configure OkHttp connect/read timeouts large enough for large paginated repository listings.","Set JVM proxy properties when behind a corporate proxy and restart the server afterwards.","Install corporate CA certificates into the JVM truststore if TLS interception is in place.","Watch the Bitbucket Cloud status page; transient outages surface as this transport-level exception."],"tags":["bitbucket-cloud","network","io-exception","connectivity"],"backgroundTag":"network-request-failed","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}