{"record":{"id":"2037c86fc2294106","repo":"redis/jedis","slug":"sethostandport-method-has-limited-capability","errorCode":null,"errorMessage":"setHostAndPort method has limited capability.","messagePattern":"setHostAndPort method has limited capability\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/JedisFactory.java","lineNumber":177,"sourceCode":"      final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {\n    if (!JedisURIHelper.isValid(uri)) {\n      throw new InvalidURIException(\n          String.format(\"Cannot open Redis connection due invalid URI. %s\", uri.toString()));\n    }\n    this.clientConfig = legacyConfigBuilderWithoutProtocolNegotiation().connectionTimeoutMillis(connectionTimeout)\n        .socketTimeoutMillis(soTimeout).blockingSocketTimeoutMillis(infiniteSoTimeout)\n        .user(JedisURIHelper.getUser(uri)).password(JedisURIHelper.getPassword(uri))\n        .database(JedisURIHelper.getDBIndex(uri)).clientName(clientName)\n        .protocol(JedisURIHelper.getRedisProtocol(uri)).ssl(JedisURIHelper.isRedisSSLScheme(uri))\n        .sslSocketFactory(sslSocketFactory).sslParameters(sslParameters)\n        .hostnameVerifier(hostnameVerifier).build();\n    this.jedisSocketFactory = new DefaultJedisSocketFactory(\n        new HostAndPort(uri.getHost(), uri.getPort()), this.clientConfig);\n  }\n\n  void setHostAndPort(final HostAndPort hostAndPort) {\n    if (!(jedisSocketFactory instanceof DefaultJedisSocketFactory)) {\n      throw new IllegalStateException(\"setHostAndPort method has limited capability.\");\n    }\n    ((DefaultJedisSocketFactory) jedisSocketFactory).updateHostAndPort(hostAndPort);\n  }\n\n  @Override\n  public void activateObject(PooledObject<Jedis> pooledJedis) throws Exception {\n    final Jedis jedis = pooledJedis.getObject();\n    if (jedis.getDB() != clientConfig.getDatabase()) {\n      jedis.select(clientConfig.getDatabase());\n    }\n  }\n\n  @Override\n  public void destroyObject(PooledObject<Jedis> pooledJedis) throws Exception {\n    final Jedis jedis = pooledJedis.getObject();\n    if (jedis.isConnected()) {\n      try {\n        jedis.close();","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/JedisFactory.java#L159-L195","documentation":"JedisFactory.setHostAndPort can only retarget the connection's socket factory if it is a DefaultJedisSocketFactory, which supports in-place host/port updates. When a custom JedisSocketFactory implementation (or a factory type that does not implement updateHostAndPort) was supplied, the client cannot be re-pointed at a new cluster node, so this IllegalStateException is thrown to fail fast instead of silently connecting to the wrong host. It is thrown inside JedisFactory.setHostAndPort (JedisFactory.java:177).","triggerScenarios":"Calling setHostAndPort on a JedisFactory (directly, or indirectly via JedisCluster topology refresh / JedisSentinelPool master switch) when the factory was constructed with a custom JedisSocketFactory that is not an instance of DefaultJedisSocketFactory.","commonSituations":"Users injecting a custom socket factory (e.g. for TLS wrappers, proxies, or custom DNS resolution) into JedisPool/JedisCluster config, then the cluster client attempts a MOVED/ASK redirect or sentinel failover and tries to update the target host.","solutions":["Extend DefaultJedisSocketFactory instead of implementing JedisSocketFactory directly, so updateHostAndPort is supported.","If a fully custom socket factory is required, create a new JedisFactory (new pool) for each host instead of calling setHostAndPort.","Wrap the call and on this error rebuild the pool/factory pointed at the new HostAndPort."],"exampleFix":"// before\nJedisFactory f = new JedisFactory(hostAndPort, clientConfig);\nf.setJedisSocketFactory(new MyCustomSocketFactory(cfg));\nf.setHostAndPort(newHostAndPort); // throws IllegalStateException\n\n// after\nJedisFactory f = new JedisFactory(newHostAndPort, clientConfig); // use DefaultJedisSocketFactory (default)\n// or extend DefaultJedisSocketFactory in MyCustomSocketFactory so updateHostAndPort works\nf.setHostAndPort(newHostAndPort);","handlingStrategy":"try-catch","validationCode":"if (!(factory.getJedisSocketFactory() instanceof DefaultJedisSocketFactory)) {\n  // rebuild factory/pool instead of calling setHostAndPort\n}","typeGuard":"boolean supportsHostUpdate(JedisFactory f) {\n  return f.getJedisSocketFactory() instanceof DefaultJedisSocketFactory;\n}","tryCatchPattern":"try {\n  factory.setHostAndPort(newHostAndPort);\n} catch (IllegalStateException e) {\n  // recreate JedisFactory/pool for newHostAndPort\n  pool = rebuildPool(newHostAndPort, clientConfig);\n}","preventionTips":["Extend DefaultJedisSocketFactory rather than implementing JedisSocketFactory from scratch when customizing sockets.","Test cluster/sentinel failover paths whenever a custom socket factory is introduced.","Prefer configuring host/port through clientConfig builders instead of mutating factories at runtime."],"tags":["java","redis","cluster","socket-factory","illegal-state"],"backgroundTag":"unsupported-operation","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"}