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
- 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.
- Always use try-with-resources so returns/broken-returns happen deterministically.
- Avoid abandoning commands mid-stream (e.g. not fully reading replies); finish or discard via a fresh connection.
- Ensure soTimeout is larger than your slowest command so replies aren't half-consumed.
- 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
- Always use try-with-resources instead of manual returnResource
- Fully consume command replies; never abandon a mid-response connection
- Set soTimeout above worst-case command time to avoid half-read replies
- Don't share a Jedis instance across threads
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
- Error while validating pooled Connection object.
- Maintenance eviction pass failed; retired connections…
- Error while validating pooled Jedis object.
- Failed to create socket.
- All configured databases are unhealthy. Cannot initialize…
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)