apache/shenyu · error · IllegalArgumentException
Redis node URL cannot be null or empty
Error message
Redis node URL cannot be null or empty
What it means
RedisConnectionFactory.parseRedisNode() validates each node string used to build a Lettuce RedisNode. A null, blank, or whitespace-only node URL carries no host information, so an IllegalArgumentException is raised before any connection is attempted.
Solutions
- Remove the blank entry from the Redis node configuration and supply a valid host (optionally host:port)
- If a value comes from an env var, verify it is set before the admin/bootstrap starts
- Trim and filter empty strings from the node list before constructing the connection factory
Example fix
// before
String[] nodes = redisUrl.split(",");
// after
List<String> nodes = Arrays.stream(redisUrl.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toList()); Defensive patterns
Strategy: validation
Validate before calling
// validate node list before building the connection factory
List<String> nodes = configuredNodes == null ? List.of()
: Arrays.stream(configuredNodes).map(String::trim).filter(s -> !s.isEmpty()).toList();
if (nodes.isEmpty()) throw new IllegalArgumentException("At least one Redis node URL is required"); Try / catch
try {
factory.create(nodes);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("cannot be null or empty")) {
logger.error("Redis node list contains a blank entry, check configuration", e);
}
throw e;
} Prevention
- Filter/trim split results from comma-separated node strings
- Fail fast at startup with a clear message when required Redis config is blank
- Prefer YAML lists over hand-split strings
- Test config loading with blank/missing values
When it happens
Trigger: Passing null/empty entries in a Redis cluster/sentinel/standalone node list (e.g. shenyu.redis.node or cluster nodes config) so parseRedisNode receives an empty string after trimming.
Common situations: Environment-variable interpolation leaving the value empty; YAML list with a blank '-' entry; a node removed from config but a trailing comma left in a comma-separated string.
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
- Port cannot be empty in Redis node URL: " + url
- Host is empty in Redis node URL: " + url
- client register param must config the appName or contextPath
- The configuration shenyu.discovery.serverList in xml/yml…
- OpenAPI pathKey cannot be null or empty
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/9e2bdbbe80202b13.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-infra/shenyu-infra-redis/src/main/java/org/apache/shenyu/infra/redis/RedisConnectionFactory.java:139
if (Objects.nonNull(redisConfigProperties.getPassword())) {
config.setPassword(RedisPassword.of(redisConfigProperties.getPassword()));
}
config.setDatabase(redisConfigProperties.getDatabase());
return config;
}
private List<RedisNode> createRedisNode(final String url) {
List<RedisNode> redisNodes = new ArrayList<>();
List<String> nodes = Lists.newArrayList(Splitter.on(";").split(url));
for (String node : nodes) {
redisNodes.add(parseRedisNode(node));
}
return redisNodes;
}
private RedisNode parseRedisNode(final String url) {
if (Objects.isNull(url) || url.trim().isEmpty()) {
throw new IllegalArgumentException("Redis node URL cannot be null or empty");
}
String trimmedUrl = url.trim();
String host = trimmedUrl;
int port = 6379;
int bracketIndex = trimmedUrl.lastIndexOf("]");
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)View on GitHub (pinned to 567142e072)