{"record":{"id":"b569810886760084","repo":"pinpoint-apm/pinpoint","slug":"invalid-argument-webhook-url","errorCode":null,"errorMessage":"Invalid argument: webhook.url","messagePattern":"Invalid argument: webhook\\.url","errorType":"validation","errorClass":"ResponseStatusException","httpStatus":400,"severity":"error","filePath":"webhook/src/main/java/com/navercorp/pinpoint/web/webhook/controller/WebhookController.java","lineNumber":56,"sourceCode":"\n    public WebhookController(WebhookService webhookService) {\n        this.webhookService = Objects.requireNonNull(webhookService, \"webhookService\");\n    }\n\n    @PostMapping()\n    public WebhookResponse insertWebhook(@RequestBody Webhook webhook) {\n\n        if (!StringUtils.hasText(webhook.getUrl()) || !(StringUtils.hasText(webhook.getApplicationName())\n                || StringUtils.hasText(webhook.getServiceName()))) {\n            logger.info(\"Missing arguments: webhook.url, applicationId/serviceName\");\n            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"Missing arguments: webhook.url and applicationId/serviceName\");\n        }\n\n        try {\n            validateURL(webhook);\n        } catch (IllegalArgumentException e) {\n            logger.info(\"Invalid argument: webhook.url\");\n            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"Invalid argument: webhook.url\");\n        }\n\n        String webhookId = webhookService.insertWebhook(webhook);\n        return new WebhookResponse(Result.SUCCESS, webhookId);\n    }\n\n    @DeleteMapping()\n    public Response deleteWebhook(@RequestBody Webhook webhook) {\n\n        if (!StringUtils.hasText(webhook.getWebhookId())) {\n            logger.info(\"Missing argument: webhookId\");\n            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"Missing argument: webhook.id\");\n        }\n        webhookService.deleteWebhook(webhook);\n        return SimpleResponse.ok();\n    }\n\n    @GetMapping()","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/webhook/src/main/java/com/navercorp/pinpoint/web/webhook/controller/WebhookController.java#L38-L74","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Validate the URL is well-formed and starts with http:// or https:// before sending","URL-encode any special characters/paths in the webhook target","If pointing at an internal service, check the module's URL validation rules (SSRF restrictions) and use an allowed host","Test the URL with a curl/browser to confirm it resolves"],"exampleFix":"// before\n{\"url\":\"hooks.example.com/abc\",\"applicationName\":\"myApp\"} // no scheme\n// after\n{\"url\":\"https://hooks.example.com/abc\",\"applicationName\":\"myApp\"}","handlingStrategy":"validation","validationCode":"function isValidWebhookUrl(url) {\n  try {\n    const u = new URL(url);\n    return u.protocol === 'http:' || u.protocol === 'https:';\n  } catch (_) {\n    return false;\n  }\n}\nif (!isValidWebhookUrl(payload.url)) throw new Error('Invalid webhook.url');","typeGuard":"function isHttpUrl(v) {\n  if (typeof v !== 'string') return false;\n  try { const u = new URL(v); return u.protocol === 'https:' || u.protocol === 'http:'; }\n  catch (_) { return false; }\n}","tryCatchPattern":"try {\n  await axios.post('/webhook', payload);\n} catch (e) {\n  if (e.response && e.response.status === 400 &&\n      String(e.response.data).includes('Invalid argument: webhook.url')) {\n    console.error('Webhook URL failed server-side validation');\n  }\n  throw e;\n}","preventionTips":["Pre-validate URLs with URL parsing and require http/https scheme","Encode special characters in path/query components","Avoid localhost/private-IP targets that SSRF guards reject","Test the endpoint is reachable before registering it as a webhook"],"tags":["http-400","webhook","url","validation"],"backgroundTag":"invalid-url-format","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}