alibaba/canal · error · IOException

Received error packet: errno = {}, sqlstate = {} errmsg = {}

Error message

Received error packet: errno = {}, sqlstate = {} errmsg = {}

What it means

Thrown while reading a binlog dump packet from the master: the first payload byte (mark) was 255, which is MySQL's ERR packet marker. The library parses errno (2 bytes), skips 1 byte, reads the 5-char sqlstate, then the remaining errmsg, and raises IOException with all three. It is the master reporting a replication-request error, not a client-side bug.

Source

Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/DirectLogFetcher.java:307

            int netnum = getUint8(PACKET_SEQ_OFFSET);
            if (!fetch0(NET_HEADER_SIZE, netlen)) {
                logger.warn("Reached end of input stream: packet #" + netnum + ", len = " + netlen);
                return false;
            }

            // Detecting error code.
            final int mark = getUint8(NET_HEADER_SIZE);
            if (mark != 0) {
                if (mark == 255) // error from master
                {
                    // Indicates an error, for example trying to fetch from
                    // wrong
                    // binlog position.
                    position = NET_HEADER_SIZE + 1;
                    final int errno = getInt16();
                    String sqlstate = forward(1).getFixString(SQLSTATE_LENGTH);
                    String errmsg = getFixString(limit - position);
                    throw new IOException("Received error packet:" + " errno = " + errno + ", sqlstate = " + sqlstate
                                          + " errmsg = " + errmsg);
                } else if (mark == 254) {
                    // Indicates end of stream. It's not clear when this would
                    // be sent.
                    logger.warn("Received EOF packet from server, apparent" + " master disconnected.");
                    return false;
                } else {
                    // Should not happen.
                    throw new IOException("Unexpected response " + mark + " while fetching binlog: packet #" + netnum
                                          + ", len = " + netlen);
                }
            }

            // The first packet is a multi-packet, concatenate the packets.
            while (netlen == MAX_PACKET_LENGTH) {
                if (!fetch0(0, NET_HEADER_SIZE)) {
                    logger.warn("Reached end of input stream while fetching header");
                    return false;

View on GitHub (pinned to 87be50e876)

Solutions

  1. Read errno/sqlstate/errmsg from the message and act on it: e.g. ER_ACCESS_DENIED_ERROR (1227) -> grant REPLICATION SLAVE; ER_MASTER_FATAL_ERROR_READING_BINLOG (1236) -> correct file/position.
  2. SHOW MASTER STATUS on the source to obtain the current valid binlog file + position before open().
  3. Ensure the connecting account has REPLICATION SLAVE (and REPLICATION CLIENT) privileges.
  4. Set a unique non-zero server_id on the replicating client.
  5. Confirm the master has log_bin enabled and the file name spelling matches exactly.

Example fix

// before - guessing the file/position
fetcher.open(conn, "mysql-bin.000001", 0L, serverId, false);

// after - query the master for the real coordinates first
try (Statement s = conn.createStatement();
     ResultSet rs = s.executeQuery("SHOW MASTER STATUS")) {
    rs.next();
    String file = rs.getString(1);
    long pos = rs.getLong(2);
    fetcher.open(conn, file, pos, serverId, false);
}
Defensive patterns

Strategy: retry

Validate before calling

// Fetch authoritative coordinates and check privileges before dumping
try (Statement s = conn.createStatement();
     ResultSet rs = s.executeQuery("SHOW MASTER STATUS")) {
    if (!rs.next()) throw new IOException("binlog disabled or no master status");
    String file = rs.getString(1); long pos = rs.getLong(2);
    // pass file/pos to open()
}

Try / catch

try { fetcher.open(conn, file, pos, serverId, false); }
catch (IOException e) {
    if (e.getMessage().startsWith("Received error packet:")) {
        // parse errno from message; on ER_MASTER_FATAL_ERROR_READING_BINLOG (1236) re-sync coordinates
        logger.error("master rejected dump: " + e.getMessage());
        resyncCoordinatesAndRetry();
    } else throw e;
}

Prevention

When it happens

Trigger: After sending COM_BINLOG_DUMP, the server replies with mark==255. Common server-side causes: the requested binlog file does not exist, the starting position is invalid/behind the master, the connecting user lacks REPLICATION SLAVE privilege, the server_id is 0 or collides, or binlogging is disabled on the master.

Common situations: Pointing at a wrong/non-existent binlog file name; requesting a position past the master's current one; a privileged proxy dropping REPLICATION SLAVE; server_id not configured; master restarted and rotated logs; reading from a replica that has no logs.

Related errors


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/78004331e2ad35e5. Report an issue: GitHub.