SonarSource/sonarqube · error · IllegalArgumentException

Could not validate GitLab read permission. Got an unexpected

Error message

Could not validate GitLab read permission. Got an unexpected answer.

What it means

Thrown by GitlabApplicationClient.checkProjectAccess when the HTTP call to the GitLab projects API throws IOException — connection failure, timeout, or stream read error. The IOException is logged and rethrown as IllegalArgumentException with the generic validation message.

Source

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

    LOG.debug("get projects : [{}]", url);
    Request.Builder builder = new Request.Builder()
      .url(url)
      .get();

    if (personalAccessToken != null) {
      builder.addHeader(PRIVATE_TOKEN, personalAccessToken);
    }

    Request request = builder.build();

    try (Response response = client.newCall(request).execute()) {
      checkResponseIsSuccessful(response, errorMessage);
      Project.parseJsonArray(response.body().string());
    } catch (JsonSyntaxException e) {
      throw new IllegalArgumentException("Could not parse GitLab answer to verify read permission. Got a non-json payload as result.");
    } catch (IOException e) {
      logException(url, e);
      throw new IllegalArgumentException(errorMessage);
    }
  }

  private static void logException(String url, IOException e) {
    String errorMessage = format("Gitlab API call to [%s] failed with error message : [%s]", url, e.getMessage());
    LOG.info(errorMessage, e);
  }

  public GsonUser checkToken(String gitlabUrl, String personalAccessToken) {
    String url = format("%s/user", gitlabUrl);

    LOG.debug("get current user : [{}]", url);
    Request.Builder builder = new Request.Builder()
      .addHeader(PRIVATE_TOKEN, personalAccessToken)
      .url(url)
      .get();

    Request request = builder.build();

View on GitHub (pinned to 184c821202)

Solutions

  1. Confirm network connectivity from the SonarQube server to the GitLab host (curl the URL from the server)
  2. Fix the gitlabUrl hostname/port and import the GitLab TLS certificate into the JVM truststore if self-signed
  3. Check the logged message 'Gitlab API call to [%s] failed...' for the underlying IOException cause

Example fix

// before: gitlabUrl = "https://gitlab.internal:8443" (port blocked)
// after: gitlabUrl = "https://gitlab.internal"; // open firewall / correct port
Defensive patterns

Strategy: try-catch

Validate before calling

curl -sS -m 10 -H "PRIVATE-TOKEN: $TOKEN" "$GITLAB_URL/api/v4/user" > /dev/null && echo reachable  # run from the SonarQube host

Try / catch

try { gitlabClient.checkReadPermission(url, token, project); } catch (IllegalArgumentException e) { log.error("GitLab connectivity problem: check URL, firewall, and TLS truststore", e); }

Prevention

When it happens

Trigger: checkReadPermission or checkUrl -> checkProjectAccess: OkHttp client.newCall(request).execute() or response.body().string() throws IOException (unreachable host, DNS failure, TLS error, timeout).

Common situations: Firewall blocks SonarQube server to GitLab; wrong hostname or port in gitlabUrl; TLS certificate not trusted by SonarQube's JVM; GitLab temporarily down.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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