SonarSource/sonarqube · error · IllegalArgumentException
Response from Azure for request [%s] could not be parsed: [%
Error message
Response from Azure for request [%s] could not be parsed: [%s]
What it means
doCall(request, handler) applies the response-parsing handler and catches JsonSyntaxException, rethrowing IllegalArgumentException with 'Response from Azure for request [%s] could not be parsed'. It means Azure answered with HTTP success but the body was not the expected JSON (Gson failed to deserialize it).
Source
Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/azure/AzureDevOpsHttpClient.java:215
checkResponseIsSuccessful(response);
} catch (IOException e) {
throw new IllegalArgumentException(
String.format(UNABLE_TO_CONTACT_AZURE_SERVER_MESSAGE_FORMAT, UNABLE_TO_CONTACT_AZURE_SERVER, request.url(), e.getMessage()),
e);
}
}
protected <G> G doGet(String token, HttpUrl url, Function<Response, G> handler) {
Request request = prepareRequestWithToken(token, GET, url, null);
return doCall(request, handler);
}
protected <G> G doCall(Request request, Function<Response, G> handler) {
try (Response response = client.newCall(request).execute()) {
checkResponseIsSuccessful(response);
return handler.apply(response);
} catch (JsonSyntaxException e) {
throw new IllegalArgumentException(
String.format("Response from Azure for request [%s] could not be parsed: [%s]", request.url(), e.getMessage()),
e);
} catch (IOException e) {
throw new IllegalArgumentException(
String.format(UNABLE_TO_CONTACT_AZURE_SERVER_MESSAGE_FORMAT, UNABLE_TO_CONTACT_AZURE_SERVER, request.url(), e.getMessage()),
e);
}
}
protected static Request prepareRequestWithToken(String token, String method, HttpUrl url, @Nullable RequestBody body) {
return new Request.Builder()
.method(method, body)
.url(url)
.addHeader("Authorization", encodeToken("accessToken:" + token))
.build();
}
protected static void checkResponseIsSuccessful(Response response) throws IOException {View on GitHub (pinned to 184c821202)
Solutions
- Log/inspect the raw response body for the failing request URL to see what was actually returned.
- Bypass or correctly authenticate the proxy/SSO that returns an HTML page instead of JSON.
- Verify the Azure DevOps Server version is supported by your SonarQube version; upgrade one side if schemas differ.
- Check for intermediate devices (proxies, WAFs) truncating or rewriting the response.
Example fix
// before: response is HTML from SSO login page // after: configure SSO bypass/allowlist for /_apis on the proxy so JSON reaches SonarQube
Defensive patterns
Strategy: try-catch
Validate before calling
static boolean looksLikeJson(Response resp) throws IOException {
String contentType = resp.header("Content-Type", "");
return contentType.contains("application/json");
} Type guard
static boolean isJsonContentType(String contentType) {
return contentType != null && contentType.toLowerCase().contains("json");
} Try / catch
try {
List<Repo> repos = client.getRepositories(pat, org);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("could not be parsed")) {
LOG.error("Azure returned a non-JSON body (proxy/SSO page?): {}", e.getCause().getMessage());
}
} Prevention
- Ensure proxies/SSO allowlist the /_apis endpoints instead of returning HTML login pages.
- Check Content-Type is application/json before parsing responses.
- Pin supported Azure DevOps Server / SonarQube version combinations.
- Inspect raw bodies in a staging environment after upgrading either product.
When it happens
Trigger: handler.apply(response) throws JsonSyntaxException during doGet: response body is HTML (login/proxy page), empty, truncated, or JSON whose shape does not match the expected DTO.
Common situations: Reverse proxy or SSO intercepting the API call and returning an HTML login page with 200; Azure DevOps Server version returning a different JSON schema; proxy mangling the body; response truncated by a network device.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- generateErrorMessage(body)
- %s for request [%s]: [%s]
- Invalid personal access token
- Invalid Azure URL
- Unexpected response from Bitbucket server
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/2936145751bed1f0.
Report an issue: GitHub.