SonarSource/sonarqube · error · IllegalArgumentException
Could not parse GitLab answer to verify read permission. Got
Error message
Could not parse GitLab answer to verify read permission. Got a non-json payload as result.
What it means
Thrown by GitlabApplicationClient.checkProjectAccess when the GitLab API returns a 2xx response but the body cannot be parsed as the expected JSON project array (JsonSyntaxException). SonarQube uses the parsed projects to verify the token's read permission on a project.
Source
Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java:113
private void checkProjectAccess(@Nullable String gitlabUrl, @Nullable String personalAccessToken, String errorMessage) {
String url = format("%s/projects", gitlabUrl);
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)View on GitHub (pinned to 184c821202)
Solutions
- Verify the configured GitLab URL points at the actual GitLab instance root (no trailing path or proxy page)
- Test the endpoint manually: curl -H 'PRIVATE-TOKEN: <token>' <gitlabUrl>/projects?membership=true
- Check for a proxy/load balancer rewriting responses to HTML error or login pages
Example fix
// before: gitlabUrl = "https://example.com/gitlab/" (proxied HTML) // after: gitlabUrl = "https://gitlab.example.com";
Defensive patterns
Strategy: try-catch
Validate before calling
curl -sS -o /dev/null -w '%{content_type}' -H "PRIVATE-TOKEN: $TOKEN" "$GITLAB_URL/api/v4/projects?membership=true" # must be application/json Try / catch
try { gitlabClient.checkReadPermission(url, token, project); } catch (IllegalArgumentException e) { if (e.getMessage().contains("non-json")) { verifyGitlabUrlAndProxy(url); } } Prevention
- Point gitlabUrl at the GitLab root, not a proxied or path-prefixed page returning HTML
- Whitelist SonarQube server IP in proxies/WAFs so real JSON reaches it
- Smoke-test the GitLab endpoint with curl after any infrastructure change
When it happens
Trigger: checkReadPermission or checkUrl -> checkProjectAccess gets an HTTP 200 whose body is not valid JSON (HTML error page, empty body, proxy interstitial), causing Gson JsonSyntaxException in Project.parseJsonArray.
Common situations: gitlabUrl points to a non-GitLab server or a reverse proxy returning HTML; wrong path behind a proxy; GitLab returns an unexpected empty 200 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
- Could not parse GitLab answer to verify token. Got a non-jso
- Could not parse GitLab answer to verify token scopes. Got a
- Could not parse GitLab answer to verify write permission. Go
- Response from Azure for request [%s] could not be parsed: [%
- Could not validate GitLab write permission. Got an unexpecte
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/cae3956664df39a1.
Report an issue: GitHub.