alibaba/canal · error · IOException
end of stream when reading header
Error message
end of stream when reading header
What it means
Thrown by the read() helper when channel.read() returns -1, meaning the remote end closed the connection before the full header buffer was filled. The connector treats truncated reads as fatal.
Source
Thrown at admin/admin-web/src/main/java/com/alibaba/otter/canal/admin/connector/SimpleAdminConnector.java:309
writeHeader.flip();
channel.write(writeHeader);
channel.write(ByteBuffer.wrap(body));
}
private byte[] readNextPacket(ReadableByteChannel channel) throws IOException {
readHeader.clear();
read(channel, readHeader);
int bodyLen = readHeader.getInt(0);
ByteBuffer bodyBuf = ByteBuffer.allocate(bodyLen).order(ByteOrder.BIG_ENDIAN);
read(channel, bodyBuf);
return bodyBuf.array();
}
private void read(ReadableByteChannel channel, ByteBuffer buffer) throws IOException {
while (buffer.hasRemaining()) {
int r = channel.read(buffer);
if (r == -1) {
throw new IOException("end of stream when reading header");
}
}
}
private void quietlyClose(Channel channel) {
try {
channel.close();
} catch (IOException e) {
logger.warn("exception on closing channel:{} \n {}", channel, e);
}
}
}
View on GitHub (pinned to 87be50e876)
Solutions
- Check that the canal-server is running and reachable (telnet/ping the admin port).
- Increase soTimeout if the idle timeout is closing the socket before operations complete.
- Reconnect (the connector resets on disconnect) and retry the operation idempotently.
- Inspect server logs for crashes/OOM/abrupt shutdowns coinciding with the disconnect.
Defensive patterns
Strategy: retry
Try / catch
try {
connector.doX();
} catch (ServiceException e) {
if (e.getCause() instanceof IOException && e.getCause().getMessage().contains("end of stream")) {
// server closed socket; reconnect and retry idempotent op once
}
throw e;
} Prevention
- Monitor canal-server health; reconnect on EOF.
- Tune soTimeout to exceed the longest expected operation.
- Make admin operations idempotent so a reconnect+retry is safe.
When it happens
Trigger: Any readNextPacket() call where the canal-server closes/resets the socket mid-packet (during handshake, auth, or an admin operation), so the 4-byte header read loop hits EOF.
Common situations: Server crash or restart mid-operation; network interruption; server-side timeout closing idle connections; firewall/proxy dropping the long-lived admin socket; the soTimeout elapsed and the socket was torn down.
Related errors
- unsupported version at this client.
- expect handshake but found other type.
- unexpected packet type when ack is expected
- something goes wrong when doing authentication: {}
- Socket already closed.
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/a8abe234da77e782.
Report an issue: GitHub.