{"record":{"id":"4d83f30badf038ef","repo":"SonarSource/sonarqube","slug":"could-not-parse-gitlab-answer-to-verify-token-got","errorCode":null,"errorMessage":"Could not parse GitLab answer to verify token. Got a non-json payload as result.","messagePattern":"Could not parse GitLab answer to verify token\\. Got a non-json payload as result\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java","lineNumber":141,"sourceCode":"  }\n\n  public GsonUser checkToken(String gitlabUrl, String personalAccessToken) {\n    String url = format(\"%s/user\", gitlabUrl);\n\n    LOG.debug(\"get current user : [{}]\", url);\n    Request.Builder builder = new Request.Builder()\n      .addHeader(PRIVATE_TOKEN, personalAccessToken)\n      .url(url)\n      .get();\n\n    Request request = builder.build();\n\n    String errorMessage = \"Could not validate GitLab token. Got an unexpected answer.\";\n    try (Response response = client.newCall(request).execute()) {\n      checkResponseIsSuccessful(response, errorMessage);\n      return GsonUser.parse(response.body().string());\n    } catch (JsonSyntaxException e) {\n      throw new IllegalArgumentException(\"Could not parse GitLab answer to verify token. Got a non-json payload as result.\");\n    } catch (IOException e) {\n      logException(url, e);\n      throw new IllegalArgumentException(errorMessage);\n    }\n  }\n\n  public GsonPersonalAccessTokenInfo getPersonalAccessTokenInfo(String gitlabUrl, String personalAccessToken) {\n    String url = format(\"%s/personal_access_tokens/self\", gitlabUrl);\n\n    LOG.debug(\"get personal access token info : [{}]\", url);\n    Request request = new Request.Builder()\n      .addHeader(PRIVATE_TOKEN, personalAccessToken)\n      .url(url)\n      .get()\n      .build();\n\n    String errorMessage = \"Could not validate GitLab token scopes. Got an unexpected answer.\";\n    try (Response response = client.newCall(request).execute()) {","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java#L123-L159","documentation":"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.","triggerScenarios":"checkToken gets an HTTP 200 whose body is not the expected JSON user object (HTML page, empty body, JSON shape mismatch), failing GsonUser.parse.","commonSituations":"URL targets something that is not GitLab; a proxy returns HTML; a GitLab version or API gateway returns an unexpected body shape.","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"],"exampleFix":"// before: gitlabUrl = \"https://example.com\" (not GitLab; returns HTML)\n// after: gitlabUrl = \"https://gitlab.example.com\";","handlingStrategy":"try-catch","validationCode":"curl -sS -H \"PRIVATE-TOKEN: $TOKEN\" \"$GITLAB_URL/api/v4/user\" | jq -e '.id'  # must return valid user JSON","typeGuard":null,"tryCatchPattern":"try { gitlabClient.checkToken(url, token); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"non-json\")) { checkProxyAndUrl(url); } }","preventionTips":["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"],"tags":["gitlab","json","token","parsing"],"backgroundTag":"invalid-json-response","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}