SonarSource/sonarqube · error · IllegalArgumentException

Authentication failed, verify the Client Id, Client Secret a

Error message

Authentication failed, verify the Client Id, Client Secret and Private Key fields

What it means

When the GET /app response returns HTTP 401 or 403, GitHub has rejected the authentication, so getAppPermissions() throws this IllegalArgumentException directing you to check the Client Id, Client Secret and Private Key. The JWT/app credentials presented were valid enough to reach GitHub but not accepted.

Source

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

  }

  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);

View on GitHub (pinned to 184c821202)

Solutions

  1. Re-verify and re-enter the App ID, Client Id, Client Secret and private key exactly as shown in the GitHub App settings
  2. Regenerate/download the private key and paste the full .pem contents
  3. Check server clock synchronization (NTP) — skewed clocks invalidate JWTs
  4. Ensure the GitHub App is installed on the target organization with approved permissions
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling, confirm credentials are non-empty and consistent
if (appId == null || clientId == null || clientSecret == null || privateKey == null) {
  throw new IllegalStateException("GitHub App credentials are not fully configured");
}

Try / catch

try {
  githubApplicationClient.validateConfig(config);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Authentication failed")) {
    // treat as credential rejection: re-enter App Id/Client Id/Client Secret/Private Key
  }
}

Prevention

When it happens

Trigger: Calling getAppPermissions with a GitHub App configuration whose JWT is rejected: expired JWT (clock skew), private key not matching the app, wrong App ID/Client Id, or the integration credentials (Client Id/Secret) being incorrect for the auth path.

Common situations: Server clock drift causing the JWT iat/exp to be invalid; rotated private key but old key still configured; App ID and Client Id swapped; Client Secret regenerated in GitHub but not updated in SonarQube; app not installed on any organization so access is forbidden.

Understand the failure class

Related errors


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