jenkinsci/jenkins · error · IOException

corrupt stream: negative operation code

Error message

corrupt stream: negative operation code

What it means

Thrown by PlainCLIProtocol.EitherSide.handle when the opcode byte read from a frame is negative (i.e. its unsigned value is > 127). The Op enum is indexed 0..n-1, so a high byte indicates the stream is corrupted or the peer is sending data that is not part of this protocol.

Source

Thrown at cli/src/main/java/hudson/cli/PlainCLIProtocol.java:189

        ProtocolException(String message) {
            super(message);
        }
    }

    abstract static class EitherSide implements Closeable {

        private final Output out;

        protected EitherSide(Output out) {
            this.out = out;
        }

        protected abstract void handleClose();

        final void handle(DataInputStream dis) throws IOException {
            byte b = dis.readByte();
            if (b < 0) { // i.e., >127
                throw new IOException("corrupt stream: negative operation code");
            }
            if (b >= Op.values().length) {
                throw new ProtocolException("unknown operation #" + b);
            }
            Op op = Op.values()[b];
            LOGGER.finest(() -> "handling frame with " + op);
            if (!handle(op, dis)) {
                throw new ProtocolException("unhandled: " + op);
            }
        }

        protected abstract boolean handle(Op op, DataInputStream dis) throws IOException;

        protected final synchronized void send(Op op) throws IOException {
            send(op, new byte[0], 0, 0);
        }

        protected final synchronized void send(Op op, int v) throws IOException {

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Reconnect with a CLI jar matching the controller version to rule out protocol skew.
  2. Check authentication and URL so no HTML/error content enters the stream.
  3. Eliminate any intermediary that modifies the streamed bytes.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    side.handle(dis);
} catch (IOException e) {
    if (e.getMessage().contains("negative operation code")) {
        // treat the connection as corrupt: tear down and reconnect with aligned versions
        connection.close();
    } else throw e;
}

Prevention

When it happens

Trigger: Payload bytes are being interpreted as an opcode because a previous frame was misaligned (wrong length), or the stream is not a PlainCLIProtocol stream at all.

Common situations: Frame-length corruption feeding garbage to the opcode reader; mid-stream injection by a proxy; protocol version skew between client and server.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/800f91cd3f572dfe. Report an issue: GitHub.