apache/shenyu · error · IllegalArgumentException

Access to private or internal IP addresses is not allowed

Error message

Access to private or internal IP addresses is not allowed

What it means

UrlSecurityUtils.validateHostForSSRF throws this IllegalArgumentException when the requested host normalizes to a private or internal IP address (e.g. 10.x, 172.16-31.x, 192.168.x). ShenYu admin validates outbound URLs to prevent SSRF attacks where a caller could make the server reach internal infrastructure. The check runs before any HTTP request is issued.

Solutions

  1. Change the URL to use a public, routable hostname/IP.
  2. If the target is intentionally internal, access it through an approved proxy or public endpoint instead of bypassing the check.
  3. Do not weaken isPrivateOrInternalIP for production; if testing, use a mock server on a non-private address or unit-test the validator directly.

Example fix

// before
String url = "http://192.168.1.10:8080/actuator/health";
UrlSecurityUtils.validateUrlForSSRF(url);
// after
String url = "https://api.example.com/actuator/health";
UrlSecurityUtils.validateUrlForSSRF(url);
Defensive patterns

Strategy: validation

Validate before calling

boolean isPrivateLiteral(String host) {
    return host.matches("^(10\\.|172\\.(1[6-9]|2\\d|3[01])\\.|192\\.168\\.|127\\.).*");
}
if (isPrivateLiteral(host)) { throw new IllegalArgumentException("private host: " + host); }

Type guard

boolean isPublicHost(String host) {
    return !(isLocalhost(host) || isPrivateOrInternalIP(host));
}

Try / catch

try {
    UrlSecurityUtils.validateUrlForSSRF(url);
} catch (IllegalArgumentException e) {
    log.warn("URL rejected by SSRF guard: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling validateUrlForSSRF/validateHostForSSRF with a URL whose host is a literal private IP (http://192.168.1.10:8080/...) or a hostname that isPrivateOrInternalIP() classifies as internal.

Common situations: Pointing health-check, divide/upstream, or config-fetch URLs at internal services during local development or in an on-prem deployment where backends genuinely live on private networks.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/7d066c652bab413f. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/UrlSecurityUtils.java:92

     * @param host the host to validate
     * @param port the port to validate
     * @throws IllegalArgumentException if the host is not allowed
     */
    public static void validateHostForSSRF(final String host, final int port) {
        if (Objects.isNull(host) || host.trim().isEmpty()) {
            throw new IllegalArgumentException("Host cannot be empty");
        }

        String normalizedHost = host.toLowerCase().trim();

        // Check for localhost variations
        if (isLocalhost(normalizedHost)) {
            throw new IllegalArgumentException("Access to localhost is not allowed");
        }

        // Check for private IP addresses
        if (isPrivateOrInternalIP(normalizedHost)) {
            throw new IllegalArgumentException("Access to private or internal IP addresses is not allowed");
        }

        // Check for sensitive ports
        if (isSensitivePort(port)) {
            throw new IllegalArgumentException("Access to sensitive ports is not allowed");
        }

        // Additional validation for DNS resolution
        try {
            InetAddress[] addresses = InetAddress.getAllByName(normalizedHost);
            for (InetAddress address : addresses) {
                if (address.isLoopbackAddress() || address.isLinkLocalAddress()
                        || address.isSiteLocalAddress() || address.isAnyLocalAddress()) {
                    throw new IllegalArgumentException("Resolved IP address is not allowed: " + address.getHostAddress());
                }

                // Check resolved IP against private ranges
                if (isPrivateIPAddress(address.getHostAddress())) {

View on GitHub (pinned to 567142e072)