SonarSource/sonarqube · error · IllegalArgumentException

%s for request [%s]: [%s]

Error message

%s for request [%s]: [%s]

What it means

isGlobalPat catches any IOException from executing the HTTP request and converts it to IllegalArgumentException with UNABLE_TO_CONTACT_AZURE_SERVER_MESSAGE_FORMAT ('%s for request [%s]: [%s]'). It means the request never got a usable HTTP response: connection or I/O failure while contacting Azure DevOps.

Source

Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/azure/AzureDevOpsHttpClient.java:185

  protected boolean isGlobalPat(String vsspsGlobalUrl, String token) {
    HttpUrl url = Objects.requireNonNull(HttpUrl.parse(vsspsGlobalUrl), INVALID_SERVER_URL)
      .newBuilder()
      .addPathSegment(PATH_APIS)
      .addPathSegment(PATH_CONNECTION_DATA)
      .addQueryParameter(PARAM_API_VERSION, API_VERSION_3_PREVIEW_VALUE)
      .build();
    Request request = prepareRequestWithToken(token, GET, url, null);
    try (Response response = globalPatProbeClient.newCall(request).execute()) {
      if (response.code() == HttpURLConnection.HTTP_OK) {
        return true;
      }
      if (response.code() == HttpURLConnection.HTTP_UNAUTHORIZED || response.code() == HttpURLConnection.HTTP_FORBIDDEN) {
        return false;
      }
      String body = Objects.requireNonNull(response.body(), MISSING_RESPONSE_BODY).string();
      throw new AzureDevopsServerException(response.code(), generateErrorMessage(body));
    } 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);
    }
  }

  private void doGet(String token, HttpUrl url) {
    Request request = prepareRequestWithToken(token, GET, url, null);
    doCall(request);
  }

  protected void doCall(Request request) {
    try (Response response = client.newCall(request).execute()) {
      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);
    }
  }

View on GitHub (pinned to 184c821202)

Solutions

  1. Fix the Azure DevOps Server URL/hostname in the devops integration settings.
  2. Test connectivity from the SonarQube server: curl -v <request URL from the message>.
  3. Import the server's TLS certificate into SonarQube's JVM truststore if the failure is a PKIX path error.
  4. Check firewall/proxy rules to allow outbound HTTPS from SonarQube to the Azure server.

Example fix

// before
URL=http://devops.server:8080 (port blocked)

// after
URL=https://devops.server.com (HTTPS, port 443 open)
Defensive patterns

Strategy: try-catch

Validate before calling

static boolean reachable(String url) {
  try {
    new java.net.URI(url).toURL().openConnection().connect();
    return true;
  } catch (IOException | IllegalArgumentException e) {
    return false;
  }
}

Try / catch

try {
  client.isGlobalPat(pat);
} catch (IllegalArgumentException e) {
  if (e.getCause() instanceof IOException io) {
    LOG.error("Cannot contact Azure DevOps ({}): {}", io.getClass().getSimpleName(), io.getMessage());
  }
  throw new ConnectivityException("Check URL/network/TLS to Azure DevOps server", e);
}

Prevention

When it happens

Trigger: client.newCall(request).execute() throws IOException during the global-PAT check: unknown host, connection refused/reset, TLS handshake failure, socket timeout, or the response body .string() call failing mid-read.

Common situations: SonarQube cannot reach the Azure DevOps Server (DNS, firewall, VPN), self-signed certificate not in the JVM truststore, wrong port, or proxy misconfiguration.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/dcd53645807335ea. Report an issue: GitHub.