{"record":{"id":"d6c996289a71ed5e","repo":"SonarSource/sonarqube","slug":"could-not-parse-gitlab-answer-when-creating-a-proj","errorCode":null,"errorMessage":"Could not parse GitLab answer when creating a project access token. Got a non-json payload as result.","messagePattern":"Could not parse GitLab answer when creating a project access 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":296,"sourceCode":"    LOG.debug(\"create project access token : [{}]\", url);\n    Request request = new Request.Builder()\n      .addHeader(PRIVATE_TOKEN, personalAccessToken)\n      .addHeader(\"Content-Type\", MediaTypes.JSON)\n      .url(url)\n      .post(RequestBody.create(requestJson.getBytes(UTF_8)))\n      .build();\n\n    try (Response response = client.newCall(request).execute()) {\n      checkResponseIsSuccessful(response, \"Could not create GitLab project access token\");\n      String body = response.body().string();\n      // Never log `body` verbatim: the create-token response's \"token\" field is the newly minted\n      // secret itself (CWE-532) — only its non-sensitive metadata is safe to trace.\n      GitlabProjectAccessToken token = new GsonBuilder().create().fromJson(body, GitlabProjectAccessToken.class);\n      LOG.trace(\"create project access token result : id=[{}] name=[{}] expires_at=[{}] scopes=[{}]\",\n        token.getId(), token.getName(), token.getExpiresAt(), token.getScopes());\n      return token;\n    } catch (JsonSyntaxException e) {\n      throw new IllegalArgumentException(\"Could not parse GitLab answer when creating a project access token. Got a non-json payload as result.\");\n    } catch (IOException e) {\n      logException(url, e);\n      throw new IllegalStateException(e.getMessage(), e);\n    }\n  }\n\n  public Project getProject(String gitlabUrl, String pat, Long gitlabProjectId) {\n    String url = format(\"%s/projects/%s\", gitlabUrl, gitlabProjectId);\n    LOG.debug(\"get project : [{}]\", url);\n    Request request = new Request.Builder()\n      .addHeader(PRIVATE_TOKEN, pat)\n      .get()\n      .url(url)\n      .build();\n\n    try (Response response = client.newCall(request).execute()) {\n      checkResponseIsSuccessful(response);\n      String body = response.body().string();","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java#L278-L314","documentation":"createProjectAccessToken POSTs to GitLab to create a project access token and parses the reply body into GitlabProjectAccessToken with Gson. If the body is not valid JSON, JsonSyntaxException is caught and IllegalArgumentException 'Could not parse GitLab answer when creating a project access token. Got a non-json payload as result.' is thrown. The token was not created (or its metadata could not be read) because the response was not the expected GitLab JSON.","triggerScenarios":"The create project access token call returns a body Gson cannot parse (HTML from a proxy/login page, empty body, or non-JSON error page) after checkResponseIsSuccessful passed, raising the error at GitlabApplicationClient.java:296.","commonSituations":"Proxy/WAF injecting HTML into the response; GitLab URL misconfigured so a web page rather than the API endpoint answers; GitLab version returning an unexpected body format for the token creation endpoint; truncated response due to network issues.","solutions":["Verify the GitLab base URL resolves to the instance root and that API calls return JSON (curl the endpoint with the PAT).","Check proxies/VPNs/WAFs between SonarQube and GitLab for HTML injection; whitelist the SonarQube server.","Retry the operation — an empty or truncated body may be transient.","Confirm the GitLab version supports the project access tokens API (GitLab 13.x+)."],"exampleFix":"// before: URL hits the web UI\nurl = https://gitlab.example.com/projects/new\n// after: correct API root\nurl = https://gitlab.example.com","handlingStrategy":"validation","validationCode":"// Ensure the token-creation endpoint answers JSON before posting\nResponse probe = call(\"GET\", gitlabUrl + \"/api/v4/version\", token);\nString ct = probe.header(\"Content-Type\", \"\");\nif (!ct.contains(\"application/json\")) throw new IllegalStateException(\"GitLab API not returning JSON (Content-Type: \" + ct + \") — check URL/proxy\");","typeGuard":null,"tryCatchPattern":"try {\n  gitlabClient.createProjectAccessToken(projectId, name, scopes);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Could not parse GitLab answer when creating a project access token\")) {\n    // inspect raw response via server log / proxy, then retry after fixing URL/proxy\n  } else { throw e; }\n}","preventionTips":["Keep proxies/WAFs from returning HTML for API paths.","Confirm the GitLab version supports project access tokens (13.x+).","Retry transient failures; empty bodies are often network truncation."],"tags":["gitlab","json","http","token","network"],"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"}