SonarSource/sonarqube · error · IllegalStateException

Failed to create the GitHub App from manifest

Error message

Failed to create the GitHub App from manifest

What it means

In convertAppManifest, an IOException during the HTTP POST to the manifest conversion endpoint is wrapped in this IllegalStateException. Unlike error 46 (bad status code), this indicates the request never completed at the transport level.

Source

Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java:426

  public GithubAppCredentials convertAppManifest(String apiEndpoint, String code) {
    String endpoint = "/app-manifests/" + URLEncoder.encode(code, StandardCharsets.UTF_8) + "/conversions";
    try {
      // Unauthenticated call: the GitHub App does not exist yet, so no JWT/app token is available.
      ApplicationHttpClient.Response response = githubApplicationHttpClient.post(apiEndpoint, null, endpoint);

      if (response.getCode() != HTTP_CREATED && response.getCode() != HTTP_OK) {
        if (LOG.isDebugEnabled()) {
          LOG.debug("GitHub manifest conversion failed, response body: {}", response.getContent().orElse(""));
        }
        throw new IllegalStateException(
          "Failed to create the GitHub App from manifest. GitHub returned code " + response.getCode());
      }

      return response.getContent()
        .map(content -> GSON.fromJson(content, GithubAppCredentials.class))
        .orElseThrow(() -> new IllegalStateException("Failed to create the GitHub App from manifest, response body was empty"));
    } catch (IOException e) {
      throw new IllegalStateException("Failed to create the GitHub App from manifest", e);
    }
  }

  @Override
  public GithubBinding.GsonApp getApp(GithubAppConfiguration githubAppConfiguration) {
    AppToken appToken = appSecurity.createAppToken(githubAppConfiguration.getId(), githubAppConfiguration.getPrivateKey());
    String endpoint = "/app";
    return getOrThrowIfNotHttpOk(githubAppConfiguration.getApiEndpoint(), appToken, endpoint, GithubBinding.GsonApp.class);
  }

  private <T> T getOrThrowIfNotHttpOk(String baseUrl, AccessToken token, String endPoint, Class<T> gsonClass) {
    try {
      GetResponse response = githubApplicationHttpClient.get(baseUrl, token, endPoint);
      if (response.getCode() != HTTP_OK) {
        throw new HttpException(baseUrl + endPoint, response.getCode(), response.getContent().orElse(""));
      }
      return handleResponse(response, endPoint, gsonClass).orElseThrow(() -> new ServerException(HTTP_INTERNAL_ERROR, "Http response withuot content"));
    } catch (IOException e) {

View on GitHub (pinned to 184c821202)

Solutions

  1. Test connectivity from the SonarQube server to the apiEndpoint host (curl -v).
  2. Fix DNS/proxy/firewall so the POST can reach GitHub.
  3. Add the instance's TLS certificate to the JVM truststore if using an internal CA.
  4. Correct the apiEndpoint value in the DevOps platform settings.

Example fix

// before
client.convertAppManifest("https://ghe-wrong-host.example.com", code);
// after
client.convertAppManifest("https://ghe.example.com/api/v3", code);
Defensive patterns

Strategy: retry

Validate before calling

// preflight reachability of the conversion endpoint
HttpResponse<String> r = HttpClient.newHttpClient().send(HttpRequest.newBuilder(URI.create(apiEndpoint)).GET().build(), BodyHandlers.ofString());
if (r.statusCode() >= 500) throw new IllegalStateException("GitHub endpoint unhealthy: " + apiEndpoint);

Try / catch

try { client.convertAppManifest(endpoint, code); } catch (IllegalStateException e) { retryWithBackoff(3, e); }

Prevention

When it happens

Trigger: Calling convertAppManifest(apiEndpoint, code) when the underlying HTTP client throws IOException — connection refused, timeout, TLS failure to apiEndpoint.

Common situations: GHES host unreachable from the SonarQube server, DNS misconfiguration, proxy blocking the POST, self-signed certificate not trusted by the JVM.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/584a3ec0f21a7ce8. Report an issue: GitHub.