SonarSource/sonarqube · error · IllegalArgumentException

Webhook URL is not valid:

Error message

Webhook URL is not valid: 

What it means

WebhookCallerImpl.call parses the webhook's URL with OkHttp's HttpUrl.parse before sending the HTTP request. If the URL is null (unparseable/malformed), it throws IllegalArgumentException "Webhook URL is not valid: <url>" and records the failure in the webhook delivery.

Solutions

  1. Edit the webhook and set a fully qualified URL starting with http:// or https://.
  2. Trim whitespace and remove illegal characters; re-encode spaces as %20.
  3. Test the URL with curl before saving it; the webhook payload will show the recorded failure.
  4. Validate the URL on webhook creation/update if using the API (api/webhooks/create).

Example fix

// before
{"url": "myserver.example.com/hooks/sonarqube"}
// after
{"url": "https://myserver.example.com/hooks/sonarqube"}
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidWebhookUrl(String url) {
  okhttp3.HttpUrl parsed = okhttp3.HttpUrl.parse(url == null ? null : url.trim());
  return parsed != null && (parsed.isHttps() || parsed.isHttp());
}

Try / catch

try { webhookCaller.call(webhook, payload); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Webhook URL is not valid")) { log.error("Fix webhook URL for {}", webhook.getName(), e); return; } throw e; }

Prevention

When it happens

Trigger: A webhook defined with a URL that OkHttp cannot parse — missing scheme, illegal characters, spaces, or a scheme-less host like 'myserver.example.com/webhook'.

Common situations: Admin creating a webhook without 'http://' or 'https://'; copy-paste with leading/trailing spaces or invisible Unicode; typos like 'htp://'.

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/204b156cd909d5a0. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-server-common/src/main/java/org/sonar/server/webhook/WebhookCallerImpl.java:76

  public WebhookCallerImpl(System2 system, OkHttpClient okHttpClient, WebhookCustomDns webhookCustomDns) {
    this.system = system;
    this.webhookCustomDns = webhookCustomDns;
    this.okHttpClient = newClientWithoutRedirect(okHttpClient, webhookCustomDns);
  }

  @Override
  public WebhookDelivery call(Webhook webhook, WebhookPayload payload) {
    WebhookDelivery.Builder builder = new WebhookDelivery.Builder();
    long startedAt = system.now();
    builder
      .setAt(startedAt)
      .setPayload(payload)
      .setWebhook(webhook);

    try {
      HttpUrl url = HttpUrl.parse(webhook.getUrl());
      if (url == null) {
        throw new IllegalArgumentException("Webhook URL is not valid: " + webhook.getUrl());
      }
      builder.setEffectiveUrl(HttpUrlHelper.obfuscateCredentials(webhook.getUrl(), url));
      validateHostIfResolvable(url);
      Request request = buildHttpRequest(url, webhook, payload);
      try (Response response = execute(request)) {
        builder.setHttpStatus(response.code());
      }
    } catch (Exception e) {
      builder.setError(e);
    }

    return builder
      .setDurationInMs((int) (system.now() - startedAt))
      .build();
  }

  private static Request buildHttpRequest(HttpUrl url, Webhook webhook, WebhookPayload payload) {
    Request.Builder request = new Request.Builder();

View on GitHub (pinned to 184c821202)