redis/jedis · critical · JedisConnectionException
It seems like server has closed the connection.
Error message
It seems like server has closed the connection.
What it means
While reading a bulk reply payload, the underlying stream returned EOF (-1) before the full declared length was read, so Jedis throws JedisConnectionException "It seems like server has closed the connection." The server (or network) dropped the connection mid-reply.
Solutions
- Retry the command on a fresh connection (enable retryable executor / retry settings).
- Enable connection validation and shorter client keep-alive so dead connections are detected before reuse.
- Increase LB/proxy idle timeouts or enable TCP keepalive on the client side.
- Check server logs for restarts/OOM and reduce value sizes or use streaming where possible.
Example fix
// before ConnectionPoolConfig pcfg = new ConnectionPoolConfig(); JedisPool pool = new JedisPool(pcfg, host, port); // after ConnectionPoolConfig pcfg = new ConnectionPoolConfig(); pcfg.setTestWhileIdle(true); pcfg.setMinEvictableIdleTimeMillis(60000); pcfg.setTimeBetweenEvictionRunsMillis(30000); // evict connections the server may have closed JedisPool pool = new JedisPool(pcfg, host, port);
Defensive patterns
Strategy: retry
Try / catch
try {
return jedis.get(key);
} catch (JedisConnectionException e) {
if (e.getMessage() != null && e.getMessage().contains("closed the connection")) {
return retryOnFreshResource(key); // server dropped mid-reply; retry once on a new connection
}
throw e;
} Prevention
- Enable pool eviction with testWhileIdle to drop server-dead connections.
- Set TCP keepalive / client timeouts below LB idle timeouts.
- Watch server logs for restarts, OOM kills, and timeout configurations.
- Avoid extremely large values that hold connections open for long reads.
When it happens
Trigger: Server closing the socket while a large bulk reply is in flight: server-side timeout, redis restart/OOM-kill, LB idle timeout, or a proxy cutting long transfers.
Common situations: Reading very large values (big GETs) through load balancers with short idle timeouts, client connections idle then reused after server timeout (matched by server-side close), or Redis crashing during a blocking command.
Related errors
- It seems like server has closed the connection.
- Unexpected end of stream.
- Attempting to write to a broken connection.
- Attempting to read from a broken connection.
- Failed to create socket.
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/bcf1a11b467e0189.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/Protocol.java:214
if (len < skipBytes) {
throw new JedisConnectionException(
"Bulk reply length " + len + " is less than expected " + skipBytes);
}
// Skip the prefix bytes
for (int i = 0; i < skipBytes; i++) {
is.readByte();
}
// Read the remaining data
final int dataLen = len - skipBytes;
final byte[] read = new byte[dataLen];
int offset = 0;
while (offset < dataLen) {
final int size = is.read(read, offset, (dataLen - offset));
if (size == -1) {
throw new JedisConnectionException("It seems like server has closed the connection.");
}
offset += size;
}
// read 2 more bytes for the command delimiter
is.readByte();
is.readByte();
return read;
}
/**
* Process a RESP3 verbatim string reply.
* Verbatim strings have format: =<length>\r\n<format>:<data>\r\n
* where <format> is a 3-character encoding hint (e.g., "txt" or "mkd").
* This method strips the 4-byte prefix (<format>:) and returns only the actual data.
*/
private static byte[] processVerbatimStringReply(final RedisInputStream is) {View on GitHub (pinned to 6dac31d4c2)