apache/shenyu · error · IllegalArgumentException

Port cannot be empty in Redis node URL: " + url

Error message

Port cannot be empty in Redis node URL: " + url

What it means

For a bracketed IPv6 node like '[::1]:', if a colon follows the closing bracket the port substring must be non-empty. '[::1]:' yields an empty port string and parseRedisNode() throws this IllegalArgumentException.

Solutions

  1. Add the port after the colon, e.g. '[::1]:6379'
  2. Remove the trailing colon entirely to use the default port 6379
  3. Set the port variable in the environment/template before deployment

Example fix

// before
redis.node: "[::1]:"
// after
redis.node: "[::1]:6379"
Defensive patterns

Strategy: validation

Validate before calling

// require digits if a port colon is present
String t = nodeUrl.trim();
int c = t.lastIndexOf(':');
if (c > 0 && c < t.length() - 1 && !t.substring(c + 1).chars().allMatch(Character::isDigit)) {
    throw new IllegalArgumentException("Port must be numeric: " + nodeUrl);
}

Try / catch

try {
    factory.create(List.of(nodeUrl));
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Port cannot be empty")) {
        logger.error("Node URL has ':' with no port digits: {}", nodeUrl, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing '[::1]:' or '[2001:db8::1]: ' (colon present, no digits after it).

Common situations: Truncated config value where the port digits were lost; template with an unset port variable rendered as nothing.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

        
        if (bracketIndex > -1) {
            // IPv6 address format: [::1] or [::1]:6379
            if (!trimmedUrl.startsWith("[")) {
                throw new IllegalArgumentException("Invalid IPv6 format in Redis node URL: " + url);
            }
            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) {

View on GitHub (pinned to 567142e072)