SonarSource/sonarqube · error · ServerException
Failed to mint a GitHub installation token for project '%s':
Error message
Failed to mint a GitHub installation token for project '%s': GitHub App API call failed
What it means
GithubInstallationTokenProviderImpl.mint() calls githubApplicationClient.createAppInstallationToken(); when the client returns Optional.empty() — the GitHub App API call did not yield a token — it logs a warning and throws ServerException(HTTP_INTERNAL_ERROR, 'Failed to mint ... GitHub App API call failed'). This signals an upstream GitHub API failure rather than a client misconfiguration.
Source
Thrown at server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/github/GithubInstallationTokenProviderImpl.java:142
// above, this isn't a "not bound" case — the binding exists, its GitHub App configuration is
// just broken (bad credentials, missing permissions, unreachable API, ...). Wrapping instead of
// rethrowing as-is adds context in one throw (S2139) while still getting the caller a distinct
// 400 instead of the same 404 as a genuinely unbound project.
throw new IllegalArgumentException(
format("Cannot mint a GitHub installation token for project '%s': invalid GitHub App configuration: %s", safeProjectKey, e.getMessage()), e);
}
Optional<Long> installationId = githubApplicationClient.getInstallationId(githubAppConfiguration, almRepo);
if (installationId.isEmpty()) {
LOG.warn("Cannot mint a GitHub installation token for project '{}': GitHub App is not installed on repository '{}'", safeProjectKey, safeAlmRepo);
return Optional.empty();
}
String repositoryName = bareRepositoryName(almRepo);
Optional<ExpiringAppInstallationToken> token = githubApplicationClient.createAppInstallationToken(githubAppConfiguration, installationId.get(), repositoryName);
if (token.isEmpty()) {
LOG.warn("Failed to mint a GitHub installation token for project '{}' (repository '{}')", safeProjectKey, safeAlmRepo);
throw new ServerException(HTTP_INTERNAL_ERROR,
format("Failed to mint a GitHub installation token for project '%s': GitHub App API call failed", safeProjectKey));
}
return Optional.of(new GithubInstallationToken(
token.get().getValue(), token.get().getExpiresAt().format(ISO_OFFSET_DATE_TIME)));
}
/**
* Strips CR/LF from user-controlled values (project key, ALM repo slug) before logging them, so a
* crafted value cannot forge extra log lines/entries (CWE-117).
*/
private static String sanitizeForLog(String value) {
return CRLF_PATTERN.matcher(value).replaceAll("_");
}
/**
* GitHub's installation-token "repositories" scoping parameter expects the bare repository name
* (no {@code owner/} prefix), unlike {@code almRepo} which is stored as {@code owner/repo}.View on GitHub (pinned to 184c821202)
Solutions
- Retry the operation after a short backoff — mint failures here are often transient GitHub-side issues
- Check GitHub status / GHES health and whether the App is hitting rate limits; reduce mint frequency or add caching of installation tokens
- Verify SonarQube-to-GitHub connectivity (proxy, TLS) with a direct API probe using the App credentials
- Inspect SonarQube server logs around the WARN line for the underlying HTTP error detail
Example fix
// before token = client.createAppInstallationToken(cfg, installationId, repo) // once, no retry // after retry with exponential backoff (e.g. 3 attempts) and cache the token until near its expiry
Defensive patterns
Strategy: retry
Validate before calling
// can't fully pre-validate an upstream outage; probe GitHub health first
const probe = await fetch(`${githubApiUrl}/api/v3/rate_limit`, { /* app creds */ }).catch(() => null);
if (!probe || !probe.ok) throw new Error('GitHub API unreachable/rate-limited; defer token minting'); Type guard
null
Try / catch
try {
const t = githubInstallationTokenProvider.getNewInstallationToken(projectKey);
} catch (ServerException e) {
if (e.getStatus() == 500 && e.getMessage().contains("GitHub App API call failed")) {
// exponential backoff retry, then surface as transient
} else throw e;
} Prevention
- Cache installation tokens until near expiry instead of minting per request
- Add exponential-backoff retries for GitHub API operations
- Monitor GitHub status/GHES maintenance windows for correlation
- Watch SonarQube server logs (WARN on mint failure) for rate-limit signals
When it happens
Trigger: GitHub API call to create the app installation token fails or returns no token while configuration and installation ID are valid — GitHub 5xx responses, rate limiting on the App, transient network errors between SonarQube and github.com (or GHES).
Common situations: GitHub incidents/outages; secondary rate limits hit by automated token-minting across many repos; GHES under maintenance; proxy timeouts.
Related errors
- Failed to check permissions with Github, check the configura
- Failed to list all repositories of '%s' accessible by user a
- Failed to get repository '%s' on '%s' (this might be related
- Failed to create GitHub's user access token. GitHub returned
- Failed to create the GitHub App from manifest. GitHub return
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/75aa9c38b74a3548.
Report an issue: GitHub.