apache/shenyu · error · IllegalArgumentException

Invalid port in Redis node URL: " + url

Error message

Invalid port in Redis node URL: " + url

What it means

When the port substring after ']' (IPv6) or after the last colon (IPv4/hostname) is not parseable as an integer, parseRedisNode() throws this IllegalArgumentException wrapping the NumberFormatException. Default port 6379 is only used when no port is specified at all.

Solutions

  1. Supply a valid numeric port (1-65535), e.g. 'localhost:6379'
  2. Omit the port entirely to use the default 6379
  3. Fix the env var/config source so the port value is numeric

Example fix

// before
redis.node: "localhost:${REDIS_PORT}"
// after (with validation)
redis.node: "localhost:6379" // or ensure REDIS_PORT="6379" is set
Defensive patterns

Strategy: validation

Validate before calling

// check port is an integer in range before config load
int c = nodeUrl.trim().lastIndexOf(':');
if (c > 0 && c < nodeUrl.length() - 1) {
    int p = Integer.parseInt(nodeUrl.substring(c + 1));
    if (p < 1 || p > 65535) throw new IllegalArgumentException("Port out of range: " + p);
}

Try / catch

try {
    factory.create(List.of(nodeUrl));
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Invalid port")) {
        logger.error("Non-numeric port in redis node: {}", nodeUrl, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing nodes like '127.0.0.1:abc', '[::1]:port', or 'localhost:99999' (out of int range is caught by parseInt too).

Common situations: Port variable interpolated as a non-numeric placeholder; port accidentally containing a unit ('6379tcp'); typo in the numeric port.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at shenyu-infra/shenyu-infra-redis/src/main/java/org/apache/shenyu/infra/redis/RedisConnectionFactory.java:169

            }
            int closingBracket = trimmedUrl.indexOf("]");
            if (closingBracket == -1 || closingBracket != bracketIndex) {
                throw new IllegalArgumentException("Invalid IPv6 format in Redis node URL: " + url);
            }
            
            // Extract IPv6 address (remove brackets)
            host = trimmedUrl.substring(1, closingBracket);
            
            // Check if port is specified after closing bracket
            if (closingBracket < trimmedUrl.length() - 1 && trimmedUrl.charAt(closingBracket + 1) == ':') {
                String portStr = trimmedUrl.substring(closingBracket + 2);
                if (portStr.isEmpty()) {
                    throw new IllegalArgumentException("Port cannot be empty in Redis node URL: " + url);
                }
                try {
                    port = Integer.parseInt(portStr);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid port in Redis node URL: " + url, e);
                }
            }
        } else {
            // IPv4 or hostname format: localhost:6379 or 192.168.1.1:6379
            int lastColonIndex = trimmedUrl.lastIndexOf(":");
            if (lastColonIndex > 0 && lastColonIndex < trimmedUrl.length() - 1) {
                String portStr = trimmedUrl.substring(lastColonIndex + 1);
                if (portStr.isEmpty()) {
                    throw new IllegalArgumentException("Port cannot be empty in Redis node URL: " + url);
                }
                try {
                    port = Integer.parseInt(portStr);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid port in Redis node URL: " + url, e);
                }
                host = trimmedUrl.substring(0, lastColonIndex);
            } else if (lastColonIndex == 0 || lastColonIndex == trimmedUrl.length() - 1) {
                throw new IllegalArgumentException("Invalid format in Redis node URL: " + url);

View on GitHub (pinned to 567142e072)