SonarSource/sonarqube · error · IllegalArgumentException

Could not parse pagination number

Error message

Could not parse pagination number

What it means

parseAndGetIntegerHeader parses a pagination header string (X-Page, X-Per-Page, X-Total) into an int. When the header value exists but is not a valid integer, Integer.parseInt throws NumberFormatException, which is wrapped in this IllegalArgumentException (with the cause preserved). GitLab returned malformed pagination metadata.

Source

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

      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) {
    return getMembers(gitlabUrl, token, format(GITLAB_GROUPS_MEMBERS_ENDPOINT + "/all", groupId));
  }

  private Set<GsonUser> getMembers(String gitlabUrl, String token, String endpoint) {
    return Set.copyOf(executePaginatedQuery(gitlabUrl, token, endpoint, resp -> parseJsonList(resp, GITLAB_USER)));

View on GitHub (pinned to 184c821202)

Solutions

  1. Inspect raw response headers (curl -i) to see the malformed pagination value.
  2. Check and fix proxy/middleware that rewrites or adds header values on GitLab responses.
  3. Ensure the configured GitLab URL targets the authentic GitLab API.
  4. If GitLab-side, check instance version and any custom response modifiers.
Defensive patterns

Strategy: validation

Validate before calling

// pre-validate header values are numeric before processing responses
boolean numeric = headerValue != null && headerValue.matches("\\d+");

Try / catch

try { ProjectList l = client.searchProjects(...); } catch (IllegalArgumentException e) { /* malformed pagination header: inspect raw headers */ }

Prevention

When it happens

Trigger: searchProjects processing a response where X-Page, X-Per-Page, or X-Total is present but non-numeric — e.g. an HTML fragment, an error message, or empty string injected by a proxy.

Common situations: Proxy/error pages rewriting header values; a non-GitLab server mimicking endpoints with bogus headers; corrupted intermediary responses; custom middleware adding unexpected header values.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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