SonarSource/sonarqube · error · GitlabServerException

GitLab Merge Request did not happen, please check your confi

Error message

GitLab Merge Request did not happen, please check your configuration

What it means

This is the fallback errorMessage passed into checkResponseIsSuccessful by the Merge Request decoration flow: when a GitLab API call fails and none of the specific cases (revoked/expired/insufficient scope, 403, 429, 401, redirect) apply, GitlabServerException is thrown with the caller-supplied message 'GitLab Merge Request did not happen, please check your configuration'. It means MR decoration failed for a generic HTTP error; the actual status and body are logged at ERROR level just before.

Source

Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java:226

    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
      }
    }
    return false;
  }

  private static boolean isTokenExpired(Response response, String body) {
    if (response.code() == HTTP_UNAUTHORIZED) {

View on GitHub (pinned to 184c821202)

Solutions

  1. Check the SonarQube server log — the full GitLab response code and body are logged at ERROR just before this exception.
  2. Verify the GitLab project identifier in SonarQube's project binding matches the real namespace/project path.
  3. Confirm the automatic MR decoration settings (GitLab URL, token, project id) and re-run Test configuration.
  4. Retry after checking GitLab instance health if the log shows a 5xx status.

Example fix

// before (binding)
project: "group/subgroup/app-name"
// after: use exact GitLab namespace/path
project: "group/subgroup/app-repo"
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight the MR decoration prerequisites
Response r = call("GET", gitlabUrl + "/api/v4/projects/" + urlEncode(projectPath) + "/merge_requests?state=opened", token);
if (r.code() == 404) throw new IllegalStateException("GitLab project '" + projectPath + "' not found — check the binding's project identifier");
if (r.code() >= 500) throw new IllegalStateException("GitLab server error " + r.code() + " — retry later");

Try / catch

catch (GitlabServerException e) {
  LOG.error("MR decoration failed: {} (http {})", e.getMessage(), e.getStatus());
  // inspect server log for the GitLab response body logged at ERROR, fix config accordingly
}

Prevention

When it happens

Trigger: A GitLab API call in the MR decoration path (e.g. listing MRs, updating commit status) returns a non-success status not covered by the specialized branches, so the else branch at GitlabApplicationClient.java:226 throws with this caller-provided errorMessage.

Common situations: MR decoration enabled but project slug/namespace wrong (404); GitLab server 5xx outage; project moved or renamed; analysis reports commit status update on a MR-less commit; unhandled GitLab error body.

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/dd895c36915eed79. Report an issue: GitHub.