redis/jedis · critical · JedisConnectionException

Attempting to write to a broken connection.

Error message

Attempting to write to a broken connection.

What it means

Connection.sendCommand() marks a connection broken when a previous I/O attempt failed. If a command is then submitted to that same broken connection, it throws JedisConnectionException with brokenCause attached instead of writing to a dead socket.

Solutions

  1. Retry the operation so the pool replaces the broken connection with a fresh one
  2. Catch JedisConnectionException and invalidate/destroy the connection rather than reusing it
  3. Verify pool eviction/test-on-borrow settings so broken connections are not handed out
  4. Check brokenCause (getCause) to diagnose the original network failure

Example fix

// before
connection.sendCommand(cmd); // reuses broken conn
// after
try {
  connection.sendCommand(cmd);
} catch (JedisConnectionException e) {
  pool.returnBrokenResource(resource);
  resource = pool.getResource();
  resource.sendCommand(cmd);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (connection.isBroken()) { connection = pool.getResource(); } // if exposed; otherwise rely on pool test-on-borrow

Try / catch

try { conn.sendCommand(args); } catch (JedisConnectionException e) { pool.returnBrokenResource(resource); resource = pool.getResource(); /* retry once */ }

Prevention

When it happens

Trigger: Reusing a Connection object after a previous send/flush IOException marked it broken; writing a command after a socket timeout or remote close on the same pooled connection instance.

Common situations: Network blips or Redis restarts mid-pipeline; very long-lived connections dropped by LB idle timeout; bug where a broken connection is returned to and reused from a pool.

Related errors


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

Appendix: source

Thrown at src/main/java/redis/clients/jedis/Connection.java:525

    sendCommand(new CommandArguments(cmd));
  }

  public void sendCommand(final ProtocolCommand cmd, Rawable keyword) {
    sendCommand(new CommandArguments(cmd).add(keyword));
  }

  public void sendCommand(final ProtocolCommand cmd, final String... args) {
    sendCommand(new CommandArguments(cmd).addObjects((Object[]) args));
  }

  public void sendCommand(final ProtocolCommand cmd, final byte[]... args) {
    sendCommand(new CommandArguments(cmd).addObjects((Object[]) args));
  }

  public void sendCommand(final CommandArguments args) {
    connect();
    if (broken) {
      throw new JedisConnectionException("Attempting to write to a broken connection.", brokenCause);
    }

    try {
      Protocol.sendCommand(outputStream, args);
    } catch (JedisConnectionException ex) {
      throw enrichWithRedisErrorLine(markBroken(ex));
    } catch (RuntimeException ex) {
      throw markBroken(ex);
    } catch (Error err) {
      throw markBroken(err);
    }
  }

  private JedisConnectionException enrichWithRedisErrorLine(JedisConnectionException ex) {
    /*
     * When client send request which formed by invalid protocol, Redis send back error message
     * before close connection. We try to read it to provide reason of failure.
     */

View on GitHub (pinned to 6dac31d4c2)