{"record":{"id":"8097e74f9d05e755","repo":"SonarSource/sonarqube","slug":"error-404-the-requested-bitbucket-server-is-unrea","errorCode":null,"errorMessage":"Error 404. The requested Bitbucket server is unreachable.","messagePattern":"Error 404\\. The requested Bitbucket server is unreachable\\.","errorType":"http","errorClass":"BitbucketServerException","httpStatus":404,"severity":"error","filePath":"server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucketserver/BitbucketServerRestClient.java","lineNumber":190,"sourceCode":"  protected static void validateResponseBody(boolean isSuccessful, String bodyString) {\n    if (isSuccessful) {\n      try {\n        buildGson().fromJson(bodyString, Object.class);\n      } catch (JsonParseException e) {\n        LOG.info(UNEXPECTED_RESPONSE_FROM_BITBUCKET_SERVER + \" : [{}]\", bodyString);\n        throw new IllegalArgumentException(UNEXPECTED_RESPONSE_FROM_BITBUCKET_SERVER, e);\n      }\n    }\n  }\n\n  protected static void handleHttpErrorIfAny(boolean isSuccessful, int httpCode, String bodyString) {\n    if (!isSuccessful) {\n      String errorMessage = getErrorMessage(bodyString);\n      LOG.info(UNABLE_TO_CONTACT_BITBUCKET_SERVER + \": {} {}\", httpCode, errorMessage);\n      if (httpCode == HTTP_UNAUTHORIZED) {\n        throw new BitbucketServerException(HTTP_UNAUTHORIZED, \"Invalid personal access token\");\n      } else if (httpCode == HTTP_NOT_FOUND) {\n        throw new BitbucketServerException(HTTP_NOT_FOUND, \"Error 404. The requested Bitbucket server is unreachable.\");\n      }\n      throw new IllegalArgumentException(UNABLE_TO_CONTACT_BITBUCKET_SERVER);\n    }\n  }\n\n  protected static boolean equals(@Nullable MediaType first, @Nullable MediaType second) {\n    String s1 = convertMediaTypeToString(first);\n    String s2 = convertMediaTypeToString(second);\n    return s1 != null && s1.equals(s2);\n  }\n\n  private static String convertMediaTypeToString(@Nullable MediaType mediaType) {\n    return Optional.ofNullable(mediaType)\n      .map(MediaType::toString)\n      .map(s -> s.toLowerCase(ENGLISH).replace(\" \", \"\"))\n      .orElse(null);\n  }\n","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucketserver/BitbucketServerRestClient.java#L172-L208","documentation":"BitbucketServerRestClient.handleHttpErrorIfAny maps HTTP response codes to exceptions. When the Bitbucket Server REST call returns 404 (HTTP_NOT_FOUND), it throws BitbucketServerException(404, \"Error 404. The requested Bitbucket server is unreachable.\"). Despite the wording, it means the server responded but the requested path/resource was not found — most often a wrong URL, wrong project/repo slug, or a proxy stripping the path.","triggerScenarios":"Any REST call made through getBodyString (e.g. validateUrl, validateToken, project/repo lookups during ALM import or PR decoration) where Bitbucket Server answers HTTP 404.","commonSituations":"Typo in the configured Bitbucket Server URL (e.g. missing or extra context path like /bitbucket); repository was renamed/deleted or the repo slug case is wrong; SonarQube pointed at the wrong base URL so /rest/api/* paths 404; a reverse proxy returns 404 for unknown hosts; SonarQube configured against Bitbucket Cloud instead of Bitbucket Server.","solutions":["Verify the Bitbucket Server URL in Administration > ALM Integrations > Bitbucket Server: it must be the server base URL including the context path (e.g. https://bitbucket.example.com/bitbucket), with no trailing path to the API","Check that the project/repo slug used by the DevOps platform binding exactly matches the Bitbucket repository slug","Test the URL manually: curl -k -u <user>:<token> <url>/rest/api/1.0/projects — if this 404s, the URL is wrong","Confirm a proxy/firewall is not returning its own 404 page; inspect the errorMessage logged by the client for the actual 404 body"],"exampleFix":"// before (wrong: includes API path or omits context path)\nalmSetting.setUrl(\"https://bitbucket.example.com/rest/api/1.0\");\n// after\ncorrectUrl = \"https://bitbucket.example.com\" + (hasContextPath ? \"/bitbucket\" : \"\");\nalmSetting.setUrl(correctUrl);","handlingStrategy":"try-catch","validationCode":"// Java: pre-check before calling the client\nURL u = new URL(bitbucketServerUrl);\nHttpURLConnection c = (HttpURLConnection) new URL(u, \"/rest/api/1.0/projects?limit=1\").openConnection();\nc.setRequestProperty(\"Authorization\", \"Bearer \" + token);\nif (c.getResponseCode() == 404) throw new IllegalStateException(\"Wrong Bitbucket Server URL or missing context path\");","typeGuard":"// Java: sanity-check the configured URL shape before calling\nstatic boolean isPlausibleBitbucketUrl(String url) {\n  try {\n    URI uri = new URI(url);\n    return uri.getScheme() != null && (uri.getScheme().equals(\"https\") || uri.getScheme().equals(\"http\")) && uri.getHost() != null;\n  } catch (URISyntaxException e) { return false; }\n}","tryCatchPattern":"try {\n  client.getRepo(projectKey, repoSlug);\n} catch (BitbucketServerException e) {\n  if (e.getStatus() == 404) {\n    // wrong URL, context path, or repo slug — re-check configuration and binding\n    throw new ConfigurationException(\"Bitbucket server URL or repository binding is wrong: \" + e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Always configure the Bitbucket Server base URL including the context path (e.g. .../bitbucket), never the API path","Cross-check repo slugs/keys used in bindings against Bitbucket exactly (case-sensitive)","Test the URL with a direct curl to /rest/api/1.0/projects before saving the integration","Watch server logs: the 404 body message is logged at INFO by the client"],"tags":["bitbucket","http-404","network","integration"],"backgroundTag":"http-error-response","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"}