{"record":{"id":"b07b6bad2015b639","repo":"apache/skywalking","slug":"pagerduty-hook-hookname-events-api-url-is-mal","errorCode":null,"errorMessage":"PagerDuty hook: [{hookName}] events-api-url is malformed: [{url}].","messagePattern":"PagerDuty hook: \\[(.+?)\\] events-api-url is malformed: \\[(.+?)\\]\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/RulesReader.java","lineNumber":401,"sourceCode":"            }\n            this.allHooks.add(settings.getFormattedName());\n        });\n    }\n\n    /**\n     * Rejects a malformed `events-api-url` while the config is being read, so a typo fails startup (or the dynamic\n     * config update) instead of surfacing later as a per-alarm {@link URI#create} failure inside the hook callback,\n     * where every alarm would be dropped with only an error log.\n     *\n     * @param url      the configured endpoint\n     * @param hookName the hook the endpoint belongs to, for the error message\n     */\n    private void validateEventsApiUrl(String url, String hookName) {\n        final URI uri;\n        try {\n            uri = new URI(url);\n        } catch (URISyntaxException e) {\n            throw new IllegalArgumentException(\n                    \"PagerDuty hook: [\" + hookName + \"] events-api-url is malformed: [\" + url + \"].\", e);\n        }\n        final String scheme = uri.getScheme();\n        if (uri.getHost() == null\n                || !(\"https\".equalsIgnoreCase(scheme) || \"http\".equalsIgnoreCase(scheme))) {\n            throw new IllegalArgumentException(\n                    \"PagerDuty hook: [\" + hookName + \"] events-api-url must be an absolute http(s) URL, but was: [\"\n                            + url + \"].\");\n        }\n        // The integration key travels in the request body, so a non-TLS endpoint puts a credential on the wire.\n        if (!\"https\".equalsIgnoreCase(scheme)) {\n            log.warn(\n                    \"PagerDuty hook [{}] is configured with a non-https events-api-url [{}]. \"\n                            + \"The integration key is sent in the request body and will not be encrypted.\",\n                    hookName, url\n            );\n        }\n    }","sourceCodeStart":383,"sourceCodeEnd":419,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/RulesReader.java#L383-L419","documentation":"IllegalArgumentException thrown by RulesReader.validateEventsApiUrl when a PagerDuty hook's `events-api-url` cannot be parsed by java.net.URI (URISyntaxException). The check runs at config-read time so a typo fails OAP startup or the dynamic config update immediately, instead of surfacing later as a per-alarm URI.create failure inside the hook callback where every alarm would be silently dropped with only an error log.","triggerScenarios":"Declaring a PagerDuty hook in alarm-settings.yml whose events-api-url contains characters URI cannot parse: spaces, unescaped brackets, a stray quote, a truncated URL (missing scheme like `events.pagerduty.com/v2/enqueue`), or copy-paste artifacts (trailing comma, surrounding quotes kept from documentation).","commonSituations":"Copy-pasting the PagerDuty URL with a trailing character; environment-variable templating that substitutes an empty or partial value; YAML multiline folding inserting a space; migrating config between Helm values files where the URL gets wrapped in quotes twice.","solutions":["Fix the URL string so it is a syntactically valid absolute URI, typically `https://events.pagerduty.com/v2/enqueue` (or your PagerDuty Events v2 regional endpoint).","Remove stray whitespace, quotes, commas, or line-wrap artifacts introduced by copy-paste or templating.","URL-encode any embedded path/query characters if you use a proxy URL with special characters.","Re-apply the config; because validation happens in RulesReader, a corrected value passes at the next OAP startup or config-center push without touching hook code."],"exampleFix":"# before\nhooks:\n  pagerduty:\n    pagerduty-hook:\n      events-api-url: https://events.pagerduty.com/v2/enqueue,   # trailing comma breaks URI parse\n# after\nhooks:\n  pagerduty:\n    pagerduty-hook:\n      events-api-url: https://events.pagerduty.com/v2/enqueue","handlingStrategy":"validation","validationCode":"// Validate before OAP load (any language / config pipeline):\ntry { new java.net.URI(url); } catch (URISyntaxException e) { /* reject config */ }\n// or in shell: python3 -c \"from urllib.parse import urlparse; urlparse('https://events.pagerduty.com/v2/enqueue')\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin the URL from an approved constant (https://events.pagerduty.com/v2/enqueue) instead of free-text entry.","Run config through a YAML+URI linter in CI before deploy.","Avoid hand-editing the URL in production; change it in the source template."],"tags":["alarm","pagerduty","webhook","config"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}