redis/jedis · warning

Resource is returned to the pool as broken

Error message

Resource is returned to the pool as broken

What it means

JedisPool.returnResource first calls resource.resetState() before returning the Jedis to the pool. If resetState (or the return path) throws a RuntimeException — usually because the connection is dead or in a bad protocol state — the object is instead returned to the pool as broken (destroyed) and this warning is logged with the cause. The caller's Jedis instance is effectively discarded; subsequent borrows get other instances.

Solutions

  1. Look at the logged exception: a socket error means the connection is gone — this is normal cleanup, ensure pool validation settings cull such connections proactively.
  2. Always use try-with-resources so returns/broken-returns happen deterministically.
  3. Avoid abandoning commands mid-stream (e.g. not fully reading replies); finish or discard via a fresh connection.
  4. Ensure soTimeout is larger than your slowest command so replies aren't half-consumed.
  5. If caused by resetState failing on DB select/auth state, verify client config matches server ACL/DB settings.

Example fix

// before
Jedis j = pool.getResource();
j.get("k"); // exception mid-call leaves state broken; manual return
pool.returnResource(j);
// after
try (Jedis j = pool.getResource()) {
  j.get("k");
} // pool handles broken return internally
Defensive patterns

Strategy: try-catch

Validate before calling

if (jedis.isConnected()) {
  jedis.ping(); // verify state before returning to pool
}

Try / catch

try (Jedis j = pool.getResource()) { j.set("k","v"); } // pool routes broken resources to returnBrokenResource internally

Prevention

When it happens

Trigger: Calling returnResource(jedis) (or closing a Jedis obtained from getResource()) when the connection's state cannot be reset — socket already closed, unread partial replies after an error, DB/state reset throwing due to a broken transport.

Common situations: Using a Jedis after the server closed the connection (timeout); abandoning a command mid-reply (e.g. after a very large response was interrupted); calling close() twice or after a network exception inside try-with-resources.

Related errors


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

Appendix: source

Thrown at src/main/java/redis/clients/jedis/JedisPool.java:412

    super(poolConfig, factory);
  }

  @Override
  public Jedis getResource() {
    Jedis jedis = super.getResource();
    jedis.setDataSource(this);
    return jedis;
  }

  @Override
  public void returnResource(final Jedis resource) {
    if (resource != null) {
      try {
        resource.resetState();
        super.returnResource(resource);
      } catch (RuntimeException e) {
        super.returnBrokenResource(resource);
        log.warn("Resource is returned to the pool as broken", e);
      }
    }
  }

  public void withResource(Consumer<Jedis> consumer) {
    try (Jedis jedis = this.getResource()) {
      consumer.accept(jedis);
    }
  }

  public <K> K withResourceGet(Function<Jedis, K> function) {
    try (Jedis jedis = this.getResource()) {
      return function.apply(jedis);
    }
  }

}

View on GitHub (pinned to 6dac31d4c2)