SonarSource/sonarqube · error · IllegalArgumentException

Pagination data from GitLab response is missing

Error message

Pagination data from GitLab response is missing

What it means

parseAndGetIntegerHeader reads the X-Page / X-Per-Page / X-Total pagination headers from a GitLab search response. If the header is absent (null), it throws this IllegalArgumentException because GitLab pagination data is mandatory for the paginated search logic. Its absence means the response did not come from a genuine GitLab projects search endpoint.

Source

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

      Headers headers = response.headers();
      checkResponseIsSuccessful(response, "Could not get projects from GitLab instance");
      List<Project> projectList = Project.parseJsonArray(response.body().string());
      int returnedPageNumber = parseAndGetIntegerHeader(headers.get("X-Page"));
      int returnedPageSize = parseAndGetIntegerHeader(headers.get("X-Per-Page"));
      String xtotal = headers.get("X-Total");
      Integer totalProjects = Strings.isEmpty(xtotal) ? null : parseAndGetIntegerHeader(xtotal);
      return new ProjectList(projectList, returnedPageNumber, returnedPageSize, totalProjects);
    } catch (JsonSyntaxException e) {
      throw new IllegalArgumentException("Could not parse GitLab answer to search projects. Got a non-json payload as result.");
    } catch (IOException e) {
      logException(url, e);
      throw new IllegalStateException(e.getMessage(), e);
    }
  }

  private static int parseAndGetIntegerHeader(@Nullable String header) {
    if (header == null) {
      throw new IllegalArgumentException("Pagination data from GitLab response is missing");
    } else {
      try {
        return Integer.parseInt(header);
      } catch (NumberFormatException e) {
        throw new IllegalArgumentException("Could not parse pagination number", e);
      }
    }
  }

  public Set<GsonGroup> getGroups(String gitlabUrl, String token) {
    return Set.copyOf(executePaginatedQuery(gitlabUrl, token, "/groups", resp -> parseJsonList(resp, GITLAB_GROUP)));
  }

  public Set<GsonUser> getDirectGroupMembers(String gitlabUrl, String token, String groupId) {
    return getMembers(gitlabUrl, token, format(GITLAB_GROUPS_MEMBERS_ENDPOINT, groupId));
  }

  public Set<GsonUser> getAllGroupMembers(String gitlabUrl, String token, String groupId) {

View on GitHub (pinned to 184c821202)

Solutions

  1. Confirm the GitLab URL points at a genuine GitLab API endpoint that returns X-Page/X-Per-Page/X-Total headers.
  2. Check proxies/gateways for header filtering and whitelist X-Page, X-Per-Page, X-Total.
  3. Test with curl -i against the same endpoint to inspect returned headers.
  4. Upgrade/verify the GitLab instance version supports pagination headers on /projects.
Defensive patterns

Strategy: validation

Validate before calling

// verify endpoint returns pagination headers before paginating
Map<String,List<String>> h = response.headers().toMultimap();
boolean ok = h.containsKey("x-page") && h.containsKey("x-per-page");

Try / catch

try { ProjectList l = client.searchProjects(...); } catch (IllegalArgumentException e) { /* missing X-Page/X-Total: endpoint or proxy stripped headers */ }

Prevention

When it happens

Trigger: searchProjects receives a 2xx response whose headers lack X-Page, X-Per-Page, or X-Total — typically because the response was produced by something other than the GitLab API (proxy, wrong URL), or a GitLab version/endpoint not returning these headers.

Common situations: Response served by a proxy or CDN that strips custom headers; pointing at a non-GitLab server that returns 200 without pagination headers; older or unusual GitLab deployments omitting X-Total on some endpoints.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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