{"record":{"id":"c5e4d42eb68d3143","repo":"redis/jedis","slug":"at-least-one-cluster-node-must-be-specified-for-cl","errorCode":null,"errorMessage":"At least one cluster node must be specified for cluster mode","messagePattern":"At least one cluster node must be specified for cluster mode","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/builders/ClusterClientBuilder.java","lineNumber":140,"sourceCode":"  protected CommandExecutor createDefaultCommandExecutor() {\n    if (this.commandFlags == null) {\n      this.commandFlags = createDefaultCommandFlagsRegistry();\n    }\n\n    Duration effectiveMaxTotalRetriesDuration = (this.maxTotalRetriesDuration == null)\n        ? Duration.ofMillis((long) this.clientConfig.getSocketTimeoutMillis() * this.maxAttempts)\n        : this.maxTotalRetriesDuration;\n\n    return new ClusterCommandExecutor((ClusterConnectionProvider) this.connectionProvider,\n        this.maxAttempts, effectiveMaxTotalRetriesDuration, this.commandFlags);\n  }\n\n  @Override\n  protected void validateSpecificConfiguration() {\n    validateCommonConfiguration();\n\n    if (nodes == null || nodes.isEmpty()) {\n      throw new IllegalArgumentException(\n          \"At least one cluster node must be specified for cluster mode\");\n    }\n\n    if (maxAttempts <= 0) {\n      throw new IllegalArgumentException(\"Max attempts must be positive for cluster mode\");\n    }\n\n    if (maxTotalRetriesDuration != null && maxTotalRetriesDuration.isNegative()) {\n      throw new IllegalArgumentException(\n          \"Max total retries duration cannot be negative for cluster mode\");\n    }\n\n    if (topologyRefreshPeriod != null && topologyRefreshPeriod.isNegative()) {\n      throw new IllegalArgumentException(\n          \"Topology refresh period cannot be negative for cluster mode\");\n    }\n  }\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/builders/ClusterClientBuilder.java#L122-L158","documentation":"RedisClusterClientBuilder requires a seed list of cluster nodes to route commands and discover the cluster topology. validateSpecificConfiguration() throws this IllegalArgumentException during build() when no nodes were provided, because a cluster client cannot function without at least one seed node to contact.","triggerScenarios":"Building a RedisClusterClient without calling .nodes(...) (or passing an empty set/list of HostAndPort), then calling build().","commonSituations":"Copy-pasting a standalone-client example and forgetting the cluster .nodes() call; constructing nodes conditionally from config and getting an empty list when the config section is missing; typos in builder method ordering.","solutions":["Provide at least one seed node via .nodes(new HostAndPort(\"127.0.0.1\", 7000)) or .nodes(Set.of(...)) before build().","If nodes come from configuration, validate the list is non-empty before constructing the builder.","Ensure you are using RedisClusterClient.builder() only when actually connecting to a cluster; otherwise use RedisClient.builder() with a single endpoint."],"exampleFix":"// before\nRedisClusterClient client = RedisClusterClient.builder()\n    .maxAttempts(5)\n    .build(); // throws\n// after\nRedisClusterClient client = RedisClusterClient.builder()\n    .nodes(new HostAndPort(\"127.0.0.1\", 7000))\n    .maxAttempts(5)\n    .build();","handlingStrategy":"validation","validationCode":"if (nodes == null || nodes.isEmpty()) {\n  throw new IllegalArgumentException(\"Provide at least one cluster node before build()\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  client = RedisClusterClient.builder().nodes(nodes).build();\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"At least one cluster node\")) {\n    throw new ConfigurationException(\"cluster nodes missing\", e);\n  }\n  throw e;\n}","preventionTips":["Load cluster seed nodes from config and assert non-empty at startup.","Always seed multiple nodes (at least 3) for resilience.","Use one builder factory method so required fields are never skipped."],"tags":["jedis","cluster","builder","configuration","missing-nodes"],"backgroundTag":"missing-required-config-field","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}