SonarSource/sonarqube · error · IllegalArgumentException

Failed to check permissions with Github, check the configura

Error message

Failed to check permissions with Github, check the configuration

What it means

getAppPermissions in GithubApplicationClientImpl validates a GitHub App's permissions by calling the GitHub API. After handling success and 401/403 cases, any other non-OK HTTP response falls through to this generic IllegalArgumentException, meaning the request failed for a reason not attributable to authentication — typically a misconfigured URL or unexpected server response. It signals the GitHub App binding configuration should be reviewed.

Source

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

  private Map<String, String> getAppPermissions(GithubAppConfiguration githubAppConfiguration) {
    AppToken appToken = appSecurity.createAppToken(githubAppConfiguration.getId(), githubAppConfiguration.getPrivateKey());

    String endPoint = "/app";
    GetResponse response;
    try {
      response = githubApplicationHttpClient.get(githubAppConfiguration.getApiEndpoint(), appToken, endPoint);
    } catch (IOException e) {
      LOG.warn(FAILED_TO_REQUEST_BEGIN_MSG + githubAppConfiguration.getApiEndpoint() + endPoint, e);
      throw new IllegalArgumentException("Failed to validate configuration, check URL and Private Key");
    }
    if (response.getCode() == HTTP_OK) {
      return handleResponse(response, endPoint, GsonApp.class)
        .map(GsonApp::getPermissions)
        .orElseThrow(() -> new IllegalArgumentException("Failed to get app permissions, unexpected response body"));
    } else if (response.getCode() == HTTP_UNAUTHORIZED || response.getCode() == HTTP_FORBIDDEN) {
      throw new IllegalArgumentException("Authentication failed, verify the Client Id, Client Secret and Private Key fields");
    } else {
      throw new IllegalArgumentException("Failed to check permissions with Github, check the configuration");
    }
  }

  private static List<String> computeMissingPermissions(Map<String, String> requiredPermissions, Map<String, String> grantedPermissions) {
    return requiredPermissions.entrySet().stream()
      .filter(permission -> !Objects.equals(permission.getValue(), grantedPermissions.get(permission.getKey())))
      .map(Map.Entry::getKey)
      // sorted for a deterministic message: REQUIRED_PERMISSIONS is a Map.of, whose iteration order is randomized per JVM
      .sorted()
      .toList();
  }

  @Override
  public Optional<Long> getInstallationId(GithubAppConfiguration githubAppConfiguration, String repositorySlug) {
    AppToken appToken = appSecurity.createAppToken(githubAppConfiguration.getId(), githubAppConfiguration.getPrivateKey());
    String endpoint = String.format("/repos/%s/installation", repositorySlug);
    return get(githubAppConfiguration.getApiEndpoint(), appToken, endpoint, GithubBinding.GsonInstallation.class)
      .map(GithubBinding.GsonInstallation::getId)

View on GitHub (pinned to 184c821202)

Solutions

  1. Verify the GitHub API URL in the SonarQube GitHub binding configuration (github-app.api.url setting) is correct for your deployment (https://api.github.com or the correct GHES endpoint).
  2. Confirm the App ID and private key correspond to an existing GitHub App (a wrong id yields 404).
  3. Enable DEBUG logging for org.sonar.alm.client to capture the endpoint and response code, then retry.
  4. Check GitHub status / network egress (proxy, firewall) for 5xx responses and retry after the outage.

Example fix

// before
GithubAppConfiguration conf = new GithubAppConfiguration(appId, privateKey, "https://ghe.example.com/api/");
// after
GithubAppConfiguration conf = new GithubAppConfiguration(appId, privateKey, "https://ghe.example.com/api/v3"); // correct GHES API path
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling
if (!appUrl.startsWith("https://")) throw new IllegalArgumentException("appUrl must be https");
// verify app resolvable: GET {appUrl}/apps/{appId} should return 200 with a valid JWT

Try / catch

try { client.getAppPermissions(conf); } catch (IllegalArgumentException e) { if (e.getMessage().contains("check the configuration")) { log.error("GitHub binding misconfigured; verify URL/AppId", e); } throw e; }

Prevention

When it happens

Trigger: getAppPermissions (via grantedPermissions or findMissingAppPermissions) receives an HTTP response whose code is not 200, 401, or 403 — e.g. 404 from a wrong API URL, 422, or 5xx from GitHub.

Common situations: Wrong GitHub API URL configured in the binding (e.g. pointing to GitHub Enterprise with a bad path), GitHub App id/private key mismatch causing a 404 on the app endpoint, transient GitHub 5xx outages, proxy interference altering responses.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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