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
- Edit the webhook and set a fully qualified URL starting with http:// or https://.
- Trim whitespace and remove illegal characters; re-encode spaces as %20.
- Test the URL with curl before saving it; the webhook payload will show the recorded failure.
- 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
- Always include http(s):// scheme when defining webhooks
- Validate URL on webhook create/update API calls
- Trim whitespace and reject non-ASCII in URLs at input time
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
- %s
- Bad format of JDBC URL
- Invalid URL
- Missing URL
- a JVM option can't be empty and must start with '-'. The…
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)