pinpoint-apm/pinpoint · error · IllegalArgumentException

Webhook URL resolved address is required

Error message

Webhook URL resolved address is required

What it means

The public validateResolvedAddress requires a non-null resolved InetAddress for the webhook host. A null address means the caller tried to validate a host whose DNS resolution produced no address, so the SSRF address policy cannot be applied. The validator fails fast rather than skipping the security check.

Solutions

  1. Ensure the host is actually resolved to an InetAddress before calling validateResolvedAddress.
  2. Handle unresolvable hosts separately (fail the webhook config with a DNS error) instead of passing null.
  3. If using a custom resolver, return an Optional/exception on failure rather than a null address.

Example fix

// before
InetAddress addr = resolver.lookupOrNull(host);
WebhookUrlValidator.validateResolvedAddress(host, addr, policy);
// after
InetAddress addr = resolver.lookup(host); // throws on failure
Objects.requireNonNull(addr, "DNS lookup failed for " + host);
WebhookUrlValidator.validateResolvedAddress(host, addr, policy);
Defensive patterns

Strategy: validation

Validate before calling

InetAddress addr = InetAddress.getByName(host);
if (addr == null) {
    throw new IllegalArgumentException("cannot resolve webhook host: " + host);
}

Type guard

boolean isResolved(InetAddress a) { return a != null && !a.isAnyLocalAddress(); }

Try / catch

try {
    WebhookUrlValidator.validateResolvedAddress(host, addr, policy);
} catch (IllegalArgumentException e) {
    log.error("Address validation failed for {}: {}", host, e.getMessage());
}

Prevention

When it happens

Trigger: Calling WebhookUrlValidator.validateResolvedAddress (directly, or via validateHostWithoutResolving on an IP literal path) with address == null while policy is non-null.

Common situations: Custom code that resolves the webhook host itself (e.g. InetAddress.getByName returning null through a custom resolver, or an empty DNS result set) and then passes the null result into validation.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/5cab612989ee58ea. Report an issue: GitHub.

Appendix: source

Thrown at commons-server/src/main/java/com/navercorp/pinpoint/common/server/webhook/WebhookUrlValidator.java:171

        return rawAuthority.indexOf(':', hostStartIndex) >= 0;
    }

    private static void validateHostWithoutResolving(String host) {
        String normalizedHost = normalizeHost(host);
        if (isBlockedHostName(normalizedHost)) {
            throw new IllegalArgumentException("Webhook URL host is not allowed");
        }

        IPAddress address = toHostLiteralAddress(normalizedHost);
        if (address != null) {
            validateResolvedAddress(normalizedHost, address.toInetAddress(), WebhookHostPolicy.denyAll());
        }
    }

    public static void validateResolvedAddress(String host, InetAddress address, WebhookHostPolicy policy) {
        Objects.requireNonNull(policy, "policy");
        if (address == null) {
            throw new IllegalArgumentException("Webhook URL resolved address is required");
        }
        if (isBlockedAddress(address)) {
            throw new IllegalArgumentException("Webhook URL resolves to a non-public address");
        }
        if (isPrivateAddress(address) && !isAllowedPrivateHost(host, policy)) {
            throw new IllegalArgumentException("Webhook URL resolves to a private address that is not allowed");
        }
    }

    /**
     * The policy matches host names only. Allowing an IP literal to match would let a caller
     * reach an internal address without going through an allowed host name.
     */
    private static boolean isAllowedPrivateHost(String host, WebhookHostPolicy policy) {
        if (host == null) {
            return false;
        }
        String normalizedHost = normalizeHost(host);

View on GitHub (pinned to 744c3d3075)