redis/jedis · error · IllegalStateException

setHostAndPort method has limited capability.

Error message

setHostAndPort method has limited capability.

What it means

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).

Solutions

  1. Extend DefaultJedisSocketFactory instead of implementing JedisSocketFactory directly, so updateHostAndPort is supported.
  2. If a fully custom socket factory is required, create a new JedisFactory (new pool) for each host instead of calling setHostAndPort.
  3. Wrap the call and on this error rebuild the pool/factory pointed at the new HostAndPort.

Example fix

// before
JedisFactory f = new JedisFactory(hostAndPort, clientConfig);
f.setJedisSocketFactory(new MyCustomSocketFactory(cfg));
f.setHostAndPort(newHostAndPort); // throws IllegalStateException

// after
JedisFactory f = new JedisFactory(newHostAndPort, clientConfig); // use DefaultJedisSocketFactory (default)
// or extend DefaultJedisSocketFactory in MyCustomSocketFactory so updateHostAndPort works
f.setHostAndPort(newHostAndPort);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!(factory.getJedisSocketFactory() instanceof DefaultJedisSocketFactory)) {
  // rebuild factory/pool instead of calling setHostAndPort
}

Type guard

boolean supportsHostUpdate(JedisFactory f) {
  return f.getJedisSocketFactory() instanceof DefaultJedisSocketFactory;
}

Try / catch

try {
  factory.setHostAndPort(newHostAndPort);
} catch (IllegalStateException e) {
  // recreate JedisFactory/pool for newHostAndPort
  pool = rebuildPool(newHostAndPort, clientConfig);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/2037c86fc2294106. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/JedisFactory.java:177

      final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
    if (!JedisURIHelper.isValid(uri)) {
      throw new InvalidURIException(
          String.format("Cannot open Redis connection due invalid URI. %s", uri.toString()));
    }
    this.clientConfig = legacyConfigBuilderWithoutProtocolNegotiation().connectionTimeoutMillis(connectionTimeout)
        .socketTimeoutMillis(soTimeout).blockingSocketTimeoutMillis(infiniteSoTimeout)
        .user(JedisURIHelper.getUser(uri)).password(JedisURIHelper.getPassword(uri))
        .database(JedisURIHelper.getDBIndex(uri)).clientName(clientName)
        .protocol(JedisURIHelper.getRedisProtocol(uri)).ssl(JedisURIHelper.isRedisSSLScheme(uri))
        .sslSocketFactory(sslSocketFactory).sslParameters(sslParameters)
        .hostnameVerifier(hostnameVerifier).build();
    this.jedisSocketFactory = new DefaultJedisSocketFactory(
        new HostAndPort(uri.getHost(), uri.getPort()), this.clientConfig);
  }

  void setHostAndPort(final HostAndPort hostAndPort) {
    if (!(jedisSocketFactory instanceof DefaultJedisSocketFactory)) {
      throw new IllegalStateException("setHostAndPort method has limited capability.");
    }
    ((DefaultJedisSocketFactory) jedisSocketFactory).updateHostAndPort(hostAndPort);
  }

  @Override
  public void activateObject(PooledObject<Jedis> pooledJedis) throws Exception {
    final Jedis jedis = pooledJedis.getObject();
    if (jedis.getDB() != clientConfig.getDatabase()) {
      jedis.select(clientConfig.getDatabase());
    }
  }

  @Override
  public void destroyObject(PooledObject<Jedis> pooledJedis) throws Exception {
    final Jedis jedis = pooledJedis.getObject();
    if (jedis.isConnected()) {
      try {
        jedis.close();

View on GitHub (pinned to 6dac31d4c2)