SonarSource/sonarqube · error · IllegalArgumentException

%s is not a valid url

Error message

%s is not a valid url

What it means

GenericApplicationHttpClient.toAbsoluteEndPoint builds an absolute URL from the ALM host plus a relative endpoint, and throws IllegalArgumentException when the concatenated host+endpoint cannot be parsed as a valid URI/URL. The failing value is reported in the message so the misconfigured input can be identified. It guards any devops-platform integration (Azure DevOps, GitHub, etc.) backed by this generic client.

Source

Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/GenericApplicationHttpClient.java:220

    Request.Builder url = new Request.Builder().url(toAbsoluteEndPoint(appUrl, endPoint));
    if (token != null) {
      url.addHeader(devopsPlatformHeaders.getAuthorizationHeader(), token.getAuthorizationHeaderPrefix() + " " + token.getValue());
      devopsPlatformHeaders.getApiVersion().ifPresent(apiVersion ->
        url.addHeader(devopsPlatformHeaders.getApiVersionHeader().orElseThrow(), apiVersion)
      );
    }
    extraHeaders.forEach(url::addHeader);
    return url;
  }

  private static String toAbsoluteEndPoint(String host, String endPoint) {
    if (endPoint.startsWith("http")) {
      return endPoint;
    }
    try {
      return new URI(host + endPoint).toURL().toExternalForm();
    } catch (URISyntaxException | IllegalArgumentException | MalformedURLException e) {
      throw new IllegalArgumentException(String.format("%s is not a valid url", host + endPoint));
    }
  }

  private static String attemptReadContent(okhttp3.Response response) {
    try {
      return readContent(response.body()).orElse(null);
    } catch (IOException e) {
      return null;
    }
  }

  private static Optional<String> readContent(@Nullable ResponseBody body) throws IOException {
    if (body == null) {
      return empty();
    }
    try {
      return of(body.string());
    } finally {

View on GitHub (pinned to 184c821202)

Solutions

  1. Fix the ALM platform URL in SonarQube project administration settings to include scheme and no illegal characters (e.g. https://server.example.com).
  2. URL-encode or remove special characters (spaces, #, %) from host and endpoint values.
  3. Verify the host setting is non-empty in sonar.properties / alm settings before saving.
  4. Escape the failing value from the message with new URI(host + endPoint) locally to pinpoint the illegal character.

Example fix

// before (settings UI)
almsettingazure=devops.company.com

// after
almsettingazure=https://devops.company.com
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidAlmUrl(String host, String endpoint) {
  String candidate = endpoint != null && endpoint.startsWith("http") ? endpoint : host + endpoint;
  try {
    new URI(candidate).toURL();
    return true;
  } catch (URISyntaxException | IllegalArgumentException | MalformedURLException e) {
    return false;
  }
}

Type guard

static boolean isValidUrl(String s) {
  if (s == null || s.isBlank()) return false;
  try { new java.net.URI(s).toURL(); return true; } catch (Exception e) { return false; }
}

Try / catch

try {
  String absolute = client.url(endpoint);
} catch (IllegalArgumentException e) {
  LOG.error("Configured ALM URL is invalid: {}", e.getMessage());
  throw new ConfigurationException("Fix the devops platform URL in settings", e);
}

Prevention

When it happens

Trigger: Calling url()/toAbsoluteEndPoint where host or endPoint is malformed: missing scheme on host (e.g. 'myserver' instead of 'https://myserver'), illegal characters (spaces, unencoded '#', '?', '|'), an empty or null host with a relative endpoint, or an endPoint that does not start with 'http' while host+endPoint still fails URI parsing.

Common situations: Users enter 'sonarqube.company.com' or 'http://server with space' in the devops platform settings form instead of a fully qualified URL; copy-pasted URLs containing trailing spaces or unencoded special characters; empty host field left after an upgrade.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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