{"record":{"id":"2f964e8acbf405bd","repo":"alibaba/Sentinel","slug":"redis-client-or-redis-cluster-client-has-not-been","errorCode":null,"errorMessage":"Redis client or Redis Cluster client has not been initialized or error occurred","messagePattern":"Redis client or Redis Cluster client has not been initialized or error occurred","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sentinel-extension/sentinel-datasource-redis/src/main/java/com/alibaba/csp/sentinel/datasource/redis/RedisDataSource.java","lineNumber":261,"sourceCode":"        }\n    }\n\n    private void loadInitialConfig() {\n        try {\n            T newValue = loadConfig();\n            if (newValue == null) {\n                RecordLog.warn(\"[RedisDataSource] WARN: initial config is null, you may have to check your data source\");\n            }\n            getProperty().updateValue(newValue);\n        } catch (Exception ex) {\n            RecordLog.warn(\"[RedisDataSource] Error when loading initial config\", ex);\n        }\n    }\n\n    @Override\n    public String readSource() {\n        if (this.redisClient == null && this.redisClusterClient == null) {\n            throw new IllegalStateException(\"Redis client or Redis Cluster client has not been initialized or error occurred\");\n        }\n\n        if (redisClient != null) {\n            RedisCommands<String, String> stringRedisCommands = redisClient.connect().sync();\n            return stringRedisCommands.get(ruleKey);\n        } else {\n            RedisAdvancedClusterCommands<String, String> stringRedisCommands = redisClusterClient.connect().sync();\n            return stringRedisCommands.get(ruleKey);\n        }\n    }\n\n    @Override\n    public void close() {\n        if (redisClient != null) {\n            redisClient.shutdown();\n        } else {\n            redisClusterClient.shutdown();\n        }","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/alibaba/Sentinel/blob/a3f40ba8e900c8489bd520274739f17235a7721c/sentinel-extension/sentinel-datasource-redis/src/main/java/com/alibaba/csp/sentinel/datasource/redis/RedisDataSource.java#L243-L279","documentation":"Thrown by RedisDataSource.readSource() when both the RedisClient and RedisClusterClient are null. As with Nacos, initialization errors are caught and only logged, so a failed Lettuce client construction leaves the fields null and each subsequent read (initial load + refresh) throws this IllegalStateException.","triggerScenarios":"Constructing RedisDataSource with a RedisConnectionConfig that Lettuce cannot use (bad host/port, unreachable Redis, auth failure), so RedisClient.create(...) throws inside the constructor; readSource() then finds both clients null.","commonSituations":"Wrong Redis host/port/password in the connection config; Redis behind a firewall or not started; using the single-node constructor against a cluster endpoint (or vice versa) so connect() fails. App starts but logs this exception from the rule-refresh thread and never loads rules.","solutions":["Inspect startup logs for '[RedisDataSource] Error occurred when initializing' or '[RedisDataSource] WARN: initial config is null' — the swallowed cause identifies the connection problem.","Verify Redis reachability and credentials from the same host: redis-cli -h <host> -p <port> -a <password> PING.","Fix RedisConnectionConfig (host/port for standalone, nodes for cluster/sentinel) and restart the application.","Test the Lettuce connection yourself before constructing the data source so a failure aborts startup with a clear error."],"exampleFix":"// before\nRedisConnectionConfig cfg = RedisConnectionConfig.builder().withHost(\"wrong-host\").build();\nnew RedisDataSource<>(cfg, ruleKey, parser);\n\n// after\nRedisConnectionConfig cfg = RedisConnectionConfig.builder().withHost(\"redis.prod\").withPort(6379).build();\nRedisClient client = RedisClient.create(cfg);           // fails fast if config is unusable\nclient.connect().sync().ping();                          // verify connectivity\nnew RedisDataSource<>(cfg, ruleKey, parser);","handlingStrategy":"try-catch","validationCode":"// pre-verify the connection before creating the data source\nRedisClient probe = RedisClient.create(cfg);\nprobe.connect().sync().ping();  // throws with a real cause if unreachable/bad auth\nprobe.shutdown();\nnew RedisDataSource<>(cfg, ruleKey, parser);","typeGuard":null,"tryCatchPattern":"try {\n    String raw = dataSource.loadConfig();\n} catch (Exception e) {\n    if (e instanceof IllegalStateException && e.getMessage().contains(\"not been initialized\")) {\n        log.error(\"Lettuce client failed to init; check Redis host/port/password and restart\", e);\n    }\n    throw e;\n}","preventionTips":["Verify Redis with redis-cli PING from the same host/network before deploying.","Use the correct constructor variant for your topology (standalone vs cluster).","Check startup logs for '[RedisDataSource] Error occurred when initializing' to find the swallowed cause."],"tags":["sentinel","datasource","redis","lettuce","initialization","runtime-error","java"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}