apache/skywalking · error · IllegalArgumentException

PagerDuty hook: [{hookName}] events-api-url is malformed: [{

Error message

PagerDuty hook: [{hookName}] events-api-url is malformed: [{url}].

What it means

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.

Source

Thrown at oap-server/server-alarm-plugin/src/main/java/org/apache/skywalking/oap/server/core/alarm/provider/RulesReader.java:401

            }
            this.allHooks.add(settings.getFormattedName());
        });
    }

    /**
     * Rejects a malformed `events-api-url` while the config is being read, so a typo fails startup (or the dynamic
     * config update) instead of surfacing later as a per-alarm {@link URI#create} failure inside the hook callback,
     * where every alarm would be dropped with only an error log.
     *
     * @param url      the configured endpoint
     * @param hookName the hook the endpoint belongs to, for the error message
     */
    private void validateEventsApiUrl(String url, String hookName) {
        final URI uri;
        try {
            uri = new URI(url);
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException(
                    "PagerDuty hook: [" + hookName + "] events-api-url is malformed: [" + url + "].", e);
        }
        final String scheme = uri.getScheme();
        if (uri.getHost() == null
                || !("https".equalsIgnoreCase(scheme) || "http".equalsIgnoreCase(scheme))) {
            throw new IllegalArgumentException(
                    "PagerDuty hook: [" + hookName + "] events-api-url must be an absolute http(s) URL, but was: ["
                            + url + "].");
        }
        // The integration key travels in the request body, so a non-TLS endpoint puts a credential on the wire.
        if (!"https".equalsIgnoreCase(scheme)) {
            log.warn(
                    "PagerDuty hook [{}] is configured with a non-https events-api-url [{}]. "
                            + "The integration key is sent in the request body and will not be encrypted.",
                    hookName, url
            );
        }
    }

View on GitHub (pinned to 102af09b4a)

Solutions

  1. 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).
  2. Remove stray whitespace, quotes, commas, or line-wrap artifacts introduced by copy-paste or templating.
  3. URL-encode any embedded path/query characters if you use a proxy URL with special characters.
  4. 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.

Example fix

# before
hooks:
  pagerduty:
    pagerduty-hook:
      events-api-url: https://events.pagerduty.com/v2/enqueue,   # trailing comma breaks URI parse
# after
hooks:
  pagerduty:
    pagerduty-hook:
      events-api-url: https://events.pagerduty.com/v2/enqueue
Defensive patterns

Strategy: validation

Validate before calling

// Validate before OAP load (any language / config pipeline):
try { new java.net.URI(url); } catch (URISyntaxException e) { /* reject config */ }
// or in shell: python3 -c "from urllib.parse import urlparse; urlparse('https://events.pagerduty.com/v2/enqueue')"

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/b07b6bad2015b639. Report an issue: GitHub.