SonarSource/sonarqube · error · IllegalArgumentException
Could not parse GitLab answer to verify token scopes. Got a
Error message
Could not parse GitLab answer to verify token scopes. Got a non-json payload as result.
What it means
Thrown by GitlabApplicationClient.getPersonalAccessTokenInfo when the GitLab /personal_access_tokens/self endpoint returns 2xx but the body is not valid JSON for a GsonPersonalAccessTokenInfo (JsonSyntaxException). Used to validate the token's scopes.
Source
Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java:163
}
}
public GsonPersonalAccessTokenInfo getPersonalAccessTokenInfo(String gitlabUrl, String personalAccessToken) {
String url = format("%s/personal_access_tokens/self", gitlabUrl);
LOG.debug("get personal access token info : [{}]", url);
Request request = new Request.Builder()
.addHeader(PRIVATE_TOKEN, personalAccessToken)
.url(url)
.get()
.build();
String errorMessage = "Could not validate GitLab token scopes. Got an unexpected answer.";
try (Response response = client.newCall(request).execute()) {
checkResponseIsSuccessful(response, errorMessage);
return GsonPersonalAccessTokenInfo.parseOne(response.body().string());
} catch (JsonSyntaxException e) {
throw new IllegalArgumentException("Could not parse GitLab answer to verify token scopes. Got a non-json payload as result.");
} catch (IOException e) {
logException(url, e);
throw new IllegalArgumentException(errorMessage);
}
}
public void checkWritePermission(String gitlabUrl, String personalAccessToken) {
String url = format("%s/markdown", gitlabUrl);
LOG.debug("verify write permission by formating some markdown : [{}]", url);
Request.Builder builder = new Request.Builder()
.url(url)
.addHeader(PRIVATE_TOKEN, personalAccessToken)
.addHeader("Content-Type", MediaTypes.JSON)
.post(RequestBody.create("{\"text\":\"validating write permission\"}".getBytes(UTF_8)));
Request request = builder.build();
View on GitHub (pinned to 184c821202)
Solutions
- Upgrade GitLab to a version that supports GET /personal_access_tokens/self (GitLab 16+)
- Verify manually: curl -H 'PRIVATE-TOKEN: <token>' <gitlabUrl>/api/v4/personal_access_tokens/self
- Confirm gitlabUrl points to the GitLab instance and not a proxy returning HTML
Example fix
// before: GitLab 15.x (endpoint returns unexpected body) // after: upgrade GitLab to >=16.0 or use a SonarQube version matching your GitLab
Defensive patterns
Strategy: try-catch
Validate before calling
curl -sS -H "PRIVATE-TOKEN: $TOKEN" "$GITLAB_URL/api/v4/personal_access_tokens/self" | jq -e '.scopes' # requires GitLab 16+
Try / catch
try { gitlabClient.getPersonalAccessTokenInfo(url, token); } catch (IllegalArgumentException e) { if (e.getMessage().contains("non-json")) { checkGitlabVersionSupportsSelfEndpoint(); } } Prevention
- Ensure GitLab is version 16+ where /personal_access_tokens/self returns the expected JSON
- Keep SonarQube and GitLab versions compatible per the SonarQube docs
- Test the endpoint response body is JSON before configuring ALM integration
When it happens
Trigger: getPersonalAccessTokenInfo receives an HTTP 200 whose body fails GsonPersonalAccessTokenInfo.parseOne — HTML response, empty body, or unexpected JSON shape (e.g. older GitLab lacking this endpoint variant).
Common situations: GitLab version too old to support /personal_access_tokens/self (added in GitLab 16); proxy interstitial; URL pointing at a non-GitLab server.
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 read permission. Got
- Could not parse GitLab answer to verify token. Got a non-jso
- Could not parse GitLab answer to verify write permission. Go
- Response from Azure for request [%s] could not be parsed: [%
- Could not validate GitLab token scopes. Got an unexpected an
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/c9b384453975c8bc.
Report an issue: GitHub.