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

  1. Retry the command on a fresh connection (enable retryable executor / retry settings).
  2. Enable connection validation and shorter client keep-alive so dead connections are detected before reuse.
  3. Increase LB/proxy idle timeouts or enable TCP keepalive on the client side.
  4. 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

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


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: =&lt;length&gt;\r\n&lt;format&gt;:&lt;data&gt;\r\n
   * where &lt;format&gt; is a 3-character encoding hint (e.g., "txt" or "mkd").
   * This method strips the 4-byte prefix (&lt;format&gt;:) and returns only the actual data.
   */
  private static byte[] processVerbatimStringReply(final RedisInputStream is) {

View on GitHub (pinned to 6dac31d4c2)