{"record":{"id":"038fb850a20d01f4","repo":"SonarSource/sonarqube","slug":"failed-to-list-all-organizations-accessible-by-use","errorCode":null,"errorMessage":"Failed to list all organizations accessible by user access token on %s","messagePattern":"Failed to list all organizations accessible by user access token on (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java","lineNumber":278,"sourceCode":"      Organizations organizations = new Organizations();\n      GetResponse response = githubApplicationHttpClient.get(appUrl, accessToken, String.format(\"/user/installations?page=%s&per_page=%s\", page, pageSize));\n      Optional<GsonInstallations> gsonInstallations = response.getContent().map(content -> GSON.fromJson(content, GsonInstallations.class));\n\n      if (!gsonInstallations.isPresent()) {\n        return organizations;\n      }\n\n      organizations.setTotal(gsonInstallations.get().getTotalCount());\n      if (gsonInstallations.get().getInstallations() != null) {\n        organizations.setOrganizations(gsonInstallations.get().getInstallations().stream()\n          .map(gsonInstallation -> new Organization(gsonInstallation.getAccount().getId(), gsonInstallation.getAccount().getLogin(), null, null, null, null, null,\n            gsonInstallation.getTargetType()))\n          .toList());\n      }\n\n      return organizations;\n    } catch (IOException e) {\n      throw new IllegalStateException(format(\"Failed to list all organizations accessible by user access token on %s\", appUrl), e);\n    }\n  }\n\n  @Override\n  public List<GithubAppInstallation> getWhitelistedGithubAppInstallations(GithubAppConfiguration githubAppConfiguration) {\n    List<GithubBinding.GsonInstallation> gsonAppInstallations = fetchAppInstallationsFromGithub(githubAppConfiguration);\n    Set<String> allowedOrganizations = gitHubSettings.getOrganizations();\n    return convertToGithubAppInstallationAndFilterWhitelisted(gsonAppInstallations, allowedOrganizations);\n  }\n\n  private static List<GithubAppInstallation> convertToGithubAppInstallationAndFilterWhitelisted(List<GithubBinding.GsonInstallation> gsonAppInstallations,\n    Set<String> allowedOrganizations) {\n    return gsonAppInstallations.stream()\n      .filter(appInstallation -> appInstallation.getAccount().getType().equalsIgnoreCase(\"Organization\"))\n      .map(GithubApplicationClientImpl::toGithubAppInstallation)\n      .filter(appInstallation -> isOrganizationWhiteListed(allowedOrganizations, appInstallation.organizationName()))\n      .toList();\n  }","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java#L260-L296","documentation":"listOrganizations fetches all GitHub organizations accessible by a user access token via the GitHub API. Any IOException during the HTTP exchange (connection failure, stream error) is wrapped in this IllegalStateException with the appUrl in the message. It indicates the request to enumerate orgs could not be completed at the transport level.","triggerScenarios":"Calling listOrganizations(appUrl, accessToken) when the underlying HTTP call throws IOException — connection refused/timeout to appUrl, TLS handshake failure, or broken response stream.","commonSituations":"GitHub Enterprise URL unreachable from the SonarQube server (firewall/DNS), self-signed certificate not in the truststore, network outage, wrong port on the GHES host.","solutions":["From the SonarQube server, test connectivity to the appUrl (curl -v https://ghe.example.com/api/v3/user/orgs).","Fix DNS/firewall/proxy so the server can reach the GitHub host on 443.","Import the GHES TLS certificate into the JVM truststore if using self-signed/internal CA.","Correct the appUrl configured in the DevOps platform integration settings."],"exampleFix":"// before\nclient.listOrganizations(\"https://ghe.internal:8443\", token);\n// after\nclient.listOrganizations(\"https://ghe.internal\", token); // reachable host, TLS terminated properly","handlingStrategy":"retry","validationCode":"// preflight connectivity\nProcess p = Runtime.getRuntime().exec(new String[]{\"curl\",\"-sf\",\"-o\",\"/dev/null\", appUrl + \"/api/v3/rate_limit\"});\nif (p.waitFor() != 0) throw new IllegalStateException(\"GitHub unreachable: \" + appUrl);","typeGuard":null,"tryCatchPattern":"try { client.listOrganizations(appUrl, token); } catch (IllegalStateException e) { retryWithBackoff(3, e); }","preventionTips":["Add JVM truststore management for GHES certificates","Use stable DNS names and health checks for the GitHub host","Configure retry with backoff for transient IO failures","Validate the appUrl in settings with a connectivity check before saving"],"tags":["github","io","network","alm-binding"],"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"}