{"record":{"id":"8d659c52501a0808","repo":"SonarSource/sonarqube","slug":"generateerrormessage-body","errorCode":null,"errorMessage":"generateErrorMessage(body)","messagePattern":"generateErrorMessage\\(body\\)","errorType":"http","errorClass":"AzureDevopsServerException","httpStatus":null,"severity":"error","filePath":"server/sonar-alm-client/src/main/java/org/sonar/alm/client/azure/AzureDevOpsHttpClient.java","lineNumber":183,"sourceCode":"  }\n\n  protected boolean isGlobalPat(String vsspsGlobalUrl, String token) {\n    HttpUrl url = Objects.requireNonNull(HttpUrl.parse(vsspsGlobalUrl), INVALID_SERVER_URL)\n      .newBuilder()\n      .addPathSegment(PATH_APIS)\n      .addPathSegment(PATH_CONNECTION_DATA)\n      .addQueryParameter(PARAM_API_VERSION, API_VERSION_3_PREVIEW_VALUE)\n      .build();\n    Request request = prepareRequestWithToken(token, GET, url, null);\n    try (Response response = globalPatProbeClient.newCall(request).execute()) {\n      if (response.code() == HttpURLConnection.HTTP_OK) {\n        return true;\n      }\n      if (response.code() == HttpURLConnection.HTTP_UNAUTHORIZED || response.code() == HttpURLConnection.HTTP_FORBIDDEN) {\n        return false;\n      }\n      String body = Objects.requireNonNull(response.body(), MISSING_RESPONSE_BODY).string();\n      throw new AzureDevopsServerException(response.code(), generateErrorMessage(body));\n    } catch (IOException e) {\n      throw new IllegalArgumentException(\n        String.format(UNABLE_TO_CONTACT_AZURE_SERVER_MESSAGE_FORMAT, UNABLE_TO_CONTACT_AZURE_SERVER, request.url(), e.getMessage()), e);\n    }\n  }\n\n  private void doGet(String token, HttpUrl url) {\n    Request request = prepareRequestWithToken(token, GET, url, null);\n    doCall(request);\n  }\n\n  protected void doCall(Request request) {\n    try (Response response = client.newCall(request).execute()) {\n      checkResponseIsSuccessful(response);\n    } catch (IOException e) {\n      throw new IllegalArgumentException(\n        String.format(UNABLE_TO_CONTACT_AZURE_SERVER_MESSAGE_FORMAT, UNABLE_TO_CONTACT_AZURE_SERVER, request.url(), e.getMessage()),\n        e);","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/azure/AzureDevOpsHttpClient.java#L165-L201","documentation":"AzureDevOpsHttpClient.isGlobalPat treats non-successful responses that are not 401/403 as an Azure-side failure and throws AzureDevopsServerException carrying the HTTP code and an error message extracted from the response body (generateErrorMessage). It occurs while checking whether a personal access token is a global (all-organizations) PAT.","triggerScenarios":"During isGlobalPat the Azure DevOps Server responds with a status other than 200 or 401/403 — e.g. 404 (wrong collection/URL), 408/503 (server overloaded), or 500 — and the response body is parsed into an error message.","commonSituations":"Typo in the Azure DevOps Server URL (missing collection name), Azure server under maintenance returning 503, proxy intercepting the request and returning a custom error page.","solutions":["Read the AzureDevopsServerException code/message: fix the URL if 404, or wait and retry if 5xx.","Verify the Azure DevOps Server base URL includes the collection path (e.g. https://server/tfs/DefaultCollection).","Check Azure DevOps Server health / event log if the code is 500/503.","If a proxy returns the error, bypass the proxy or trust it for SonarQube requests."],"exampleFix":"// before\nURL=https://devops.server.com (missing collection)\n\n// after\nURL=https://devops.server.com/DefaultCollection","handlingStrategy":"try-catch","validationCode":"// verify server URL exists before isGlobalPat-style checks\nHttpResponse<String> resp = httpClient.send(request, HttpResponse.BodyHandlers.ofString());\nif (resp.statusCode() == 404) {\n  throw new IllegalArgumentException(\"Azure DevOps URL invalid: check collection path\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  boolean global = client.isGlobalPat(pat);\n} catch (AzureDevopsServerException e) {\n  switch (e.getCode()) {\n    case 404: throw new ConfigurationException(\"Invalid Azure URL/collection\", e);\n    case 503: /* retry later */ break;\n    default:  throw new ConfigurationException(\"Azure server error \" + e.getCode(), e);\n  }\n}","preventionTips":["Include the collection path in Azure DevOps Server URLs.","Validate the server URL in a browser before configuring the integration.","Monitor Azure DevOps Server health during maintenance windows.","Check what the response body says — it is embedded in the exception message."],"tags":["java","azure-devops","http"],"backgroundTag":"upstream-api-error","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"}