{"record":{"id":"9e2bdbbe80202b13","repo":"apache/shenyu","slug":"redis-node-url-cannot-be-null-or-empty","errorCode":null,"errorMessage":"Redis node URL cannot be null or empty","messagePattern":"Redis node URL cannot be null or empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"shenyu-infra/shenyu-infra-redis/src/main/java/org/apache/shenyu/infra/redis/RedisConnectionFactory.java","lineNumber":139,"sourceCode":"        if (Objects.nonNull(redisConfigProperties.getPassword())) {\n            config.setPassword(RedisPassword.of(redisConfigProperties.getPassword()));\n        }\n        config.setDatabase(redisConfigProperties.getDatabase());\n        return config;\n    }\n\n    private List<RedisNode> createRedisNode(final String url) {\n        List<RedisNode> redisNodes = new ArrayList<>();\n        List<String> nodes = Lists.newArrayList(Splitter.on(\";\").split(url));\n        for (String node : nodes) {\n            redisNodes.add(parseRedisNode(node));\n        }\n        return redisNodes;\n    }\n\n    private RedisNode parseRedisNode(final String url) {\n        if (Objects.isNull(url) || url.trim().isEmpty()) {\n            throw new IllegalArgumentException(\"Redis node URL cannot be null or empty\");\n        }\n        \n        String trimmedUrl = url.trim();\n        String host = trimmedUrl;\n        int port = 6379;\n        int bracketIndex = trimmedUrl.lastIndexOf(\"]\");\n        \n        if (bracketIndex > -1) {\n            // IPv6 address format: [::1] or [::1]:6379\n            if (!trimmedUrl.startsWith(\"[\")) {\n                throw new IllegalArgumentException(\"Invalid IPv6 format in Redis node URL: \" + url);\n            }\n            int closingBracket = trimmedUrl.indexOf(\"]\");\n            if (closingBracket == -1 || closingBracket != bracketIndex) {\n                throw new IllegalArgumentException(\"Invalid IPv6 format in Redis node URL: \" + url);\n            }\n            \n            // Extract IPv6 address (remove brackets)","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-infra/shenyu-infra-redis/src/main/java/org/apache/shenyu/infra/redis/RedisConnectionFactory.java#L121-L157","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nString[] nodes = redisUrl.split(\",\");\n// after\nList<String> nodes = Arrays.stream(redisUrl.split(\",\"))\n    .map(String::trim)\n    .filter(s -> !s.isEmpty())\n    .collect(Collectors.toList());","handlingStrategy":"validation","validationCode":"// validate node list before building the connection factory\nList<String> nodes = configuredNodes == null ? List.of()\n    : Arrays.stream(configuredNodes).map(String::trim).filter(s -> !s.isEmpty()).toList();\nif (nodes.isEmpty()) throw new IllegalArgumentException(\"At least one Redis node URL is required\");","typeGuard":null,"tryCatchPattern":"try {\n    factory.create(nodes);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"cannot be null or empty\")) {\n        logger.error(\"Redis node list contains a blank entry, check configuration\", e);\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["redis","configuration","validation"],"backgroundTag":"empty-required-field","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}