SonarSource/sonarqube · error · IllegalArgumentException
Could not parse GitLab answer to verify token. Got a non-jso
Error message
Could not parse GitLab answer to verify token. Got a non-json payload as result.
What it means
Thrown by GitlabApplicationClient.checkToken when the GitLab /user endpoint returns a 2xx response but the body is not valid JSON for a GsonUser (JsonSyntaxException). This validates the personal access token during ALM configuration.
Source
Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java:141
}
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)
.get();
Request request = builder.build();
String errorMessage = "Could not validate GitLab token. Got an unexpected answer.";
try (Response response = client.newCall(request).execute()) {
checkResponseIsSuccessful(response, errorMessage);
return GsonUser.parse(response.body().string());
} catch (JsonSyntaxException e) {
throw new IllegalArgumentException("Could not parse GitLab answer to verify token. Got a non-json payload as result.");
} catch (IOException e) {
logException(url, e);
throw new IllegalArgumentException(errorMessage);
}
}
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()) {View on GitHub (pinned to 184c821202)
Solutions
- Verify gitlabUrl is the GitLab instance root and reachable directly
- Test manually: curl -H 'PRIVATE-TOKEN: <token>' <gitlabUrl>/user and confirm JSON output
- Inspect any proxy in front of GitLab that may inject HTML or modify the response body
Example fix
// before: gitlabUrl = "https://example.com" (not GitLab; returns HTML) // after: gitlabUrl = "https://gitlab.example.com";
Defensive patterns
Strategy: try-catch
Validate before calling
curl -sS -H "PRIVATE-TOKEN: $TOKEN" "$GITLAB_URL/api/v4/user" | jq -e '.id' # must return valid user JSON
Try / catch
try { gitlabClient.checkToken(url, token); } catch (IllegalArgumentException e) { if (e.getMessage().contains("non-json")) { checkProxyAndUrl(url); } } Prevention
- Validate the token manually against /api/v4/user before entering it in settings
- Ensure gitlabUrl is the bare instance URL; the client appends API paths
- Watch for proxies returning HTML login pages to unauthenticated-seeming clients
When it happens
Trigger: checkToken gets an HTTP 200 whose body is not the expected JSON user object (HTML page, empty body, JSON shape mismatch), failing GsonUser.parse.
Common situations: URL targets something that is not GitLab; a proxy returns HTML; a GitLab version or API gateway returns an unexpected body shape.
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 scopes. Got a
- Could not parse GitLab answer to verify write permission. Go
- Could not parse GitLab answer when creating a project access
- Response from Azure for request [%s] could not be parsed: [%
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/4d83f30badf038ef.
Report an issue: GitHub.