pinpoint-apm/pinpoint · error · ResponseStatusException

Invalid argument: webhook.url

Error message

Invalid argument: webhook.url

What it means

After the presence check, insertWebhook runs validateURL(webhook); if the URL is malformed or disallowed (e.g. not http/https, unparseable, blocked host) it throws IllegalArgumentException which is converted to a 400 ResponseStatusException 'Invalid argument: webhook.url'. The webhook is not created.

Solutions

  1. Validate the URL is well-formed and starts with http:// or https:// before sending
  2. URL-encode any special characters/paths in the webhook target
  3. If pointing at an internal service, check the module's URL validation rules (SSRF restrictions) and use an allowed host
  4. Test the URL with a curl/browser to confirm it resolves

Example fix

// before
{"url":"hooks.example.com/abc","applicationName":"myApp"} // no scheme
// after
{"url":"https://hooks.example.com/abc","applicationName":"myApp"}
Defensive patterns

Strategy: validation

Validate before calling

function isValidWebhookUrl(url) {
  try {
    const u = new URL(url);
    return u.protocol === 'http:' || u.protocol === 'https:';
  } catch (_) {
    return false;
  }
}
if (!isValidWebhookUrl(payload.url)) throw new Error('Invalid webhook.url');

Type guard

function isHttpUrl(v) {
  if (typeof v !== 'string') return false;
  try { const u = new URL(v); return u.protocol === 'https:' || u.protocol === 'http:'; }
  catch (_) { return false; }
}

Try / catch

try {
  await axios.post('/webhook', payload);
} catch (e) {
  if (e.response && e.response.status === 400 &&
      String(e.response.data).includes('Invalid argument: webhook.url')) {
    console.error('Webhook URL failed server-side validation');
  }
  throw e;
}

Prevention

When it happens

Trigger: POST webhook with a URL that fails validateURL — malformed URL (no scheme, spaces, bad characters), unsupported protocol, or a URL deemed unsafe (e.g. targeting internal hosts).

Common situations: Typo'd URLs like 'htp://...' or missing scheme 'hooks.example.com/x'; URLs with unencoded spaces or unicode; SSRF-guard rejecting localhost/private IPs; trailing junk copied from docs.

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 pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/b569810886760084. Report an issue: GitHub.

Appendix: source

Thrown at webhook/src/main/java/com/navercorp/pinpoint/web/webhook/controller/WebhookController.java:56

    public WebhookController(WebhookService webhookService) {
        this.webhookService = Objects.requireNonNull(webhookService, "webhookService");
    }

    @PostMapping()
    public WebhookResponse insertWebhook(@RequestBody Webhook webhook) {

        if (!StringUtils.hasText(webhook.getUrl()) || !(StringUtils.hasText(webhook.getApplicationName())
                || StringUtils.hasText(webhook.getServiceName()))) {
            logger.info("Missing arguments: webhook.url, applicationId/serviceName");
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Missing arguments: webhook.url and applicationId/serviceName");
        }

        try {
            validateURL(webhook);
        } catch (IllegalArgumentException e) {
            logger.info("Invalid argument: webhook.url");
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid argument: webhook.url");
        }

        String webhookId = webhookService.insertWebhook(webhook);
        return new WebhookResponse(Result.SUCCESS, webhookId);
    }

    @DeleteMapping()
    public Response deleteWebhook(@RequestBody Webhook webhook) {

        if (!StringUtils.hasText(webhook.getWebhookId())) {
            logger.info("Missing argument: webhookId");
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Missing argument: webhook.id");
        }
        webhookService.deleteWebhook(webhook);
        return SimpleResponse.ok();
    }

    @GetMapping()

View on GitHub (pinned to 744c3d3075)