jenkinsci/jenkins · error · IOException
corrupt stream: negative frame length
Error message
corrupt stream: negative frame length
What it means
Thrown by PlainCLIProtocol.FramedReader when the 4-byte frame length read from the stream is negative. The protocol defines each frame as a nonnegative int length followed by a one-byte opcode and payload; a negative length is impossible in a well-formed stream and signals corruption or a version/protocol mismatch.
Source
Thrown at cli/src/main/java/hudson/cli/PlainCLIProtocol.java:136
cis = new CountingInputStream(is);
flightRecorder = new FlightRecorderInputStream(cis);
dis = new DataInputStream(flightRecorder);
}
@Override
public void run() {
try {
while (true) {
LOGGER.finest("reading frame");
int framelen;
try {
framelen = dis.readInt();
} catch (EOFException x) {
side.handleClose();
break; // TODO verify that we hit EOF immediately, not partway into framelen
}
if (framelen < 0) {
throw new IOException("corrupt stream: negative frame length");
}
LOGGER.finest("read frame length " + framelen);
long start = cis.getByteCount();
try {
side.handle(new DataInputStream(new BoundedInputStream(dis, /* op byte not counted */framelen + 1)));
} catch (ProtocolException x) {
LOGGER.log(Level.WARNING, null, x);
// but read another frame
} finally {
long actuallyRead = cis.getByteCount() - start;
long unread = framelen + 1 - actuallyRead;
if (unread > 0) {
LOGGER.warning(() -> "Did not read " + unread + " bytes");
IOUtils.skipFully(dis, unread);
}
}
}
} catch (ClosedChannelException x) {View on GitHub (pinned to 2e228ff40b)
Solutions
- Verify the -s URL and credentials so Jenkins returns the framed protocol rather than an error/login page.
- Use a CLI jar version matching the controller to avoid framing disagreements.
- Inspect the network path for any proxy that might alter the response body.
Defensive patterns
Strategy: try-catch
Try / catch
try {
new PlainCLIProtocol.FramedReader(connection, is).start();
} catch (IOException e) {
if (e.getMessage().contains("negative frame length")) {
// reconnect with a matched CLI jar version; the stream was not the expected protocol
} else throw e;
} Prevention
- Use a CLI jar downloaded from the target controller to avoid framing mismatches.
- Keep the CLI connection free of intercepting proxies.
- Authenticate so Jenkins returns framed bytes rather than a login page.
When it happens
Trigger: The bytes being read are not actually a PlainCLIProtocol stream (e.g. an HTML error page, an HTTP chunk header, or random data), or the two sides disagree on framing (one side sending Remoting, the expecting plain).
Common situations: A proxy injecting content into the CLI stream; server returning a login/error page instead of framed bytes; client and server CLI protocol versions mismatched; connection half-closed and reusing a stale socket.
Related errors
- corrupt stream: negative operation code
- expected to see initial zero byte; perhaps you are connectin
- unknown operation #{}
- unhandled: {}
- There's no Jenkins running at {}
AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14).
Data as JSON: /api/errors/e8ce4f7406859952.
Report an issue: GitHub.