SonarSource/sonarqube · error · IllegalArgumentException

Could not parse GitLab answer to retrieve a project. Got a n

Error message

Could not parse GitLab answer to retrieve a project. Got a non-json payload as result.

What it means

getProject fetches a single GitLab project via the GitLab API and deserializes the JSON body into a Project object with Gson. When the response body is not valid JSON, Gson throws JsonSyntaxException, which is rethrown as this IllegalArgumentException with the original parse exception swallowed. This means GitLab returned something unexpected (HTML error page, empty body, proxy page) instead of the expected project JSON.

Source

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

    }
  }

  public Project getProject(String gitlabUrl, String pat, Long gitlabProjectId) {
    String url = format("%s/projects/%s", gitlabUrl, gitlabProjectId);
    LOG.debug("get project : [{}]", url);
    Request request = new Request.Builder()
      .addHeader(PRIVATE_TOKEN, pat)
      .get()
      .url(url)
      .build();

    try (Response response = client.newCall(request).execute()) {
      checkResponseIsSuccessful(response);
      String body = response.body().string();
      LOG.trace("loading project payload result : [{}]", body);
      return new GsonBuilder().create().fromJson(body, Project.class);
    } catch (JsonSyntaxException e) {
      throw new IllegalArgumentException("Could not parse GitLab answer to retrieve a project. Got a non-json payload as result.");
    } catch (IOException e) {
      logException(url, e);
      throw new IllegalStateException(e.getMessage(), e);
    }
  }

  //
  // This method is used to check if a user has REPORTER level access to the project, which is a requirement for PR decoration.
  // As of June 9, 2021 there is no better way to do this check and still support GitLab 11.7.
  //
  public Optional<Project> getReporterLevelAccessProject(String gitlabUrl, String pat, Long gitlabProjectId) {
    String url = format("%s/projects?min_access_level=20&id_after=%s&id_before=%s", gitlabUrl, gitlabProjectId - 1,
      gitlabProjectId + 1);
    LOG.debug("get project : [{}]", url);
    Request request = new Request.Builder()
      .addHeader(PRIVATE_TOKEN, pat)
      .get()
      .url(url)

View on GitHub (pinned to 184c821202)

Solutions

  1. Verify the configured GitLab URL is correct and points directly at the GitLab instance, not through a proxy that injects HTML.
  2. Check the token: use a personal access token, not an OAuth redirect flow that might yield an HTML login page.
  3. Inspect network path (VPN, corporate proxy, SSO) for components that return HTML with 2xx status codes.
  4. Enable trace logging (loading project payload result) to capture the actual body and diagnose what GitLab returned.

Example fix

// before: swallowed JsonSyntaxException hides the cause
throw new IllegalArgumentException("Could not parse GitLab answer to retrieve a project. Got a non-json payload as result.");
// after: log the body first, as done at trace level, to see what came back
LOG.trace("loading project payload result : [{}]", body);
return new GsonBuilder().create().fromJson(body, Project.class);
Defensive patterns

Strategy: try-catch

Validate before calling

if (gitlabUrl == null || !gitlabUrl.startsWith("http")) throw new IllegalArgumentException("GitLab URL must be configured");

Try / catch

try { project = gitlabClient.getProject(url, token, repo); } catch (IllegalArgumentException e) { LOG.error("GitLab returned non-JSON payload; check URL/proxy config", e); }

Prevention

When it happens

Trigger: Calling getProject(url, token, projectIdentifier) when the GitLab HTTP response (already verified as a 2xx status by checkResponseIsSuccessful) contains a body that fails Gson parsing — e.g. an HTML page from a reverse proxy, an empty body, or a plain-text message instead of JSON.

Common situations: A reverse proxy or corporate gateway intercepts the request and returns an HTML 2xx page; the GitLab URL points at a non-API endpoint or wrong host; SSO/redirect middleware returns HTML; a misconfigured load balancer returns an empty body.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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