redis/jedis · error · JedisConnectionException
Unexpected end of stream.
Error message
Unexpected end of stream.
What it means
ensureFill refills the internal buffer from the socket; when read() returns -1 the stream has reached EOF, meaning the server (or an intermediary) closed the TCP connection while Jedis still expected reply bytes. Jedis wraps this in JedisConnectionException("Unexpected end of stream.").
Solutions
- Treat the connection as broken: close it and retry the command on a new connection.
- Configure pool validation (testWhileIdle, evictor) so dead connections are not handed out.
- Set socket timeout below server `timeout` and LB idle timeout; enable TCP keepalive.
- Inspect Redis server logs for shutdowns, OOM, or client kills at the failure timestamp.
Example fix
// before GenericObjectPoolConfig cfg = new GenericObjectPoolConfig(); cfg.setTestOnBorrow(false); // after GenericObjectPoolConfig cfg = new GenericObjectPoolConfig(); cfg.setTestWhileIdle(true); cfg.setTimeBetweenEvictionRunsMillis(30000); cfg.setMinEvictableIdleTimeMillis(60000);
Defensive patterns
Strategy: retry
Try / catch
RetryTemplate-style:
for (int attempt = 0; attempt < 2; attempt++) {
try (Jedis j = pool.getResource()) {
return j.get(key);
} catch (JedisConnectionException e) {
if (attempt == 1) throw e;
// else fall through and retry on a fresh connection
}
} Prevention
- Configure pool eviction and validation to prune dead idle connections.
- Align socket timeout with server `timeout` and infrastructure idle limits.
- Monitor Redis restarts/OOM events; alert on server-side client kills.
- Retry idempotent commands with backoff.
When it happens
Trigger: Thrown from ensureFill (used by peek, readByte, ensureCrLf, readLine, readLineBytes, readLineBytesSlowly) whenever more bytes are needed but the socket delivers EOF.
Common situations: Redis restarted or OOM-killed mid-command; server closed an idle connection (server `timeout`); LB/firewall silently dropping idle flows; command sent, then network drop before reply.
Related errors
- It seems like server has closed the connection.
- Failed to create socket.
- It seems like server has closed the connection.
- All configured databases are unhealthy. Cannot initialize…
- Attempting to write to a broken connection.
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/18d08ab80087d56d.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/util/RedisInputStream.java:259
ensureFill();
final int length = Math.min(limit - count, len);
System.arraycopy(buf, count, b, off, length);
count += length;
return length;
}
/**
* This method assumes there are required bytes to be read. If we cannot read anymore bytes an
* exception is thrown to quickly ascertain that the stream was smaller than expected.
*/
private void ensureFill() throws JedisConnectionException {
if (count >= limit) {
try {
limit = in.read(buf);
count = 0;
if (limit == -1) {
throw new JedisConnectionException("Unexpected end of stream.");
}
} catch (IOException e) {
throw new JedisConnectionException(e);
}
}
}
@Override
public int available() throws IOException {
int availableInBuf = limit - count;
int availableInSocket = this.in.available();
return (availableInBuf > availableInSocket) ? availableInBuf : availableInSocket;
}
}
View on GitHub (pinned to 6dac31d4c2)