SonarSource/sonarqube · warning
Failed to count GitHub repos for ALM setting
Error message
Failed to count GitHub repos for ALM setting '{}' What it means
OnboardingAlmConfiguration counts GitHub repositories for an ALM setting by paging the GitHub search API and summing repo totals. On any failure it logs this warning including the setting key and returns OptionalLong.empty(), degrading gracefully.
Solutions
- Check the attached exception for HTTP status/rate-limit details from GitHub
- Validate the GitHub token/app configuration for the ALM setting (re-authenticate if expired)
- Test connectivity from the SonarQube host to api.github.com
- Retry later if rate-limited; the UI treats empty count as 'unknown'
Defensive patterns
Strategy: fallback
Validate before calling
if (setting == null || setting.key() == null || tokenIsBlank(setting)) return OptionalLong.empty();
Try / catch
try { return OptionalLong.of(total); } catch (Exception e) { LOG.warn("Failed to count GitHub repos for ALM setting '{}'", key, e); return OptionalLong.empty(); } Prevention
- Rotate and validate GitHub tokens before expiry
- Handle GitHub rate limits with backoff
- Keep egress to api.github.com open from the server
When it happens
Trigger: fetchTotalCount for a GitHub provider throws — HTTP errors from GitHub API, invalid/expired token, rate limiting, or unexpected response shape — when counting repos for the given alm setting key.
Common situations: Expired or revoked GitHub PAT; GitHub API rate limit; network egress blocked from SonarQube to github.com; deleted or renamed GitHub app installation.
Related errors
- Authentication failed, verify the Client Id, Client Secret…
- Cannot mint a GitHub installation token for project
- Cannot mint a GitHub installation token for project
- Cannot mint a GitHub installation token: project
- Cannot mint a GitHub installation token: project
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/ccd9d4d3203fd4af.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/onboarding/alm/OnboardingAlmConfiguration.java:150
long appId = Long.parseLong(rawAppId.trim());
String privateKey = decryptor.decrypt(rawPrivateKey);
if (privateKey == null) {
return OptionalLong.empty();
}
var config = new GithubAppConfiguration(appId, privateKey, url);
long total = 0;
for (var installation : client.getWhitelistedGithubAppInstallations(config)) {
var token = client.createAppInstallationToken(config, Long.parseLong(installation.installationId()));
if (token.isPresent()) {
var repos = client.listRepositories(url, token.get(), installation.organizationName(), null, 1, 1);
if (repos != null) {
total += repos.getTotal();
}
}
}
return OptionalLong.of(total);
} catch (Exception e) {
LOG.warn("Failed to count GitHub repos for ALM setting '{}'", setting.key(), e);
return OptionalLong.empty();
}
}
}
/**
* Common shape shared by every ALM whose count is fetched with a single access-token-bearing
* client call, where that token comes straight off the setting itself: check the two required
* setting fields once, decrypt the secret, then delegate to {@link #countRepos}. Fields are
* captured into locals exactly once and never re-read off {@code setting} afterward, since a
* value re-read after crossing another method call (the decrypt) can no longer be proven
* non-null by the caller. Bitbucket Cloud does NOT extend this: its token never comes from the
* setting at all (see {@link BitbucketCloudAlmRepoCountProvider}), so it implements
* {@link AlmRepoCountProvider} directly instead.
*/
private abstract static class PatAlmRepoCountProvider implements AlmRepoCountProvider {
protected String primaryField(OnboardingRows.AlmSetting setting) {View on GitHub (pinned to 184c821202)