SonarSource/sonarqube · warning · GitlabServerException
GitLab API rate limit exceeded. Try again later.
Error message
GitLab API rate limit exceeded. Try again later.
What it means
checkResponseIsSuccessful translates GitLab's HTTP 429 (Too Many Requests) into GitlabServerException 'GitLab API rate limit exceeded. Try again later.' SonarQube made more GitLab API requests than the instance allows per window; the call failed client-throttling, not because of configuration.
Source
Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java:220
protected static void checkResponseIsSuccessful(Response response) throws IOException {
checkResponseIsSuccessful(response, "GitLab Merge Request did not happen, please check your configuration");
}
protected static void checkResponseIsSuccessful(Response response, String errorMessage) throws IOException {
if (!response.isSuccessful()) {
String body = response.body().string();
LOG.error("Gitlab API call to [{}] failed with {} http code. gitlab response content : [{}]", response.request().url(), response.code(), body);
if (isTokenRevoked(response, body)) {
throw new GitlabServerException(response.code(), "Your GitLab token was revoked");
} else if (isTokenExpired(response, body)) {
throw new GitlabServerException(response.code(), "Your GitLab token is expired");
} else if (isInsufficientScope(response, body)) {
throw new GitlabServerException(response.code(), "Your GitLab token has insufficient scope");
} else if (response.code() == HTTP_FORBIDDEN) {
throw new GitlabServerException(response.code(), "Forbidden access to GitLab. Verify your token's permissions and IP restrictions.");
} else if (response.code() == HTTP_TOO_MANY_REQUESTS) {
throw new GitlabServerException(response.code(), "GitLab API rate limit exceeded. Try again later.");
} else if (response.code() == HTTP_UNAUTHORIZED) {
throw new GitlabServerException(response.code(), "Invalid personal access token");
} else if (response.isRedirect()) {
throw new GitlabServerException(response.code(), "Request was redirected, please provide the correct URL");
} else {
throw new GitlabServerException(response.code(), errorMessage);
}
}
}
private static boolean isTokenRevoked(Response response, String body) {
if (response.code() == HTTP_UNAUTHORIZED) {
try {
Optional<GsonError> gitlabError = GsonError.parseOne(body);
return gitlabError.map(GsonError::getErrorDescription).map(description -> description.contains("Token was revoked")).orElse(false);
} catch (JsonParseException e) {
// nothing to do
}View on GitHub (pinned to 184c821202)
Solutions
- Wait for the rate-limit window to reset and retry the operation.
- Reduce parallelism: import/analyze projects in smaller batches or stagger CI jobs.
- Raise rate limits in GitLab (Admin Area > Settings > Network > User and IP rate limits) or on the reverse proxy.
- Ensure SonarQube traffic is authenticated (authenticated users get higher limits than anonymous).
Example fix
// before: import all 500 projects at once
parallelImport(projects);
// after: batch with delay
projects.stream().collect(batching(50)).forEach(batch -> { importBatch(batch); sleep(backoff); }); Defensive patterns
Strategy: retry
Try / catch
catch (GitlabServerException e) {
if ("GitLab API rate limit exceeded. Try again later.".equals(e.getMessage())) {
long wait = Math.min(60, (long) Math.pow(2, attempt)) * 1000L; // exponential backoff, max 60s
Thread.sleep(wait);
retry();
} else { throw e; }
} Prevention
- Throttle bulk project imports and stagger CI-triggered analyses.
- Tune GitLab rate limits for the SonarQube server's traffic volume.
- Monitor 429 occurrences and back off automatically instead of hot-looping.
When it happens
Trigger: Any GitLab API call via checkResponseIsSuccessful (checkProjectAccess, checkToken, getPersonalAccessTokenInfo, checkWritePermission, createProjectAccessToken) receives 429 at GitlabApplicationClient.java:220 — typically during bulk imports or CI-heavy periods with many concurrent analyses.
Common situations: Large onboarding importing many GitLab projects at once; many CI jobs starting analyses simultaneously; GitLab instance or reverse proxy (nginx) with low rate limits; shared NAT making many SonarQube requests appear from one IP.
Related errors
- Could not validate GitLab read permission. Got an unexpected
- Could not validate GitLab token. Got an unexpected answer.
- Could not validate GitLab token scopes. Got an unexpected an
- Could not validate GitLab write permission. Got an unexpecte
- Forbidden access to GitLab. Verify your token's permissions
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/9dfc051912030083.
Report an issue: GitHub.