alibaba/canal · error · IOException

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

Error message

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

What it means

Thrown as IOException('Received error packet') when the MySQL master returns error packet mark 255 during binlog streaming, but the error message does NOT match the 'purged logs' patterns of error 402. This is the catch-all for any non-purge replication error returned by the master while Canal is actively reading the binlog stream via DirectLogFetcher.fetch().

Source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/DirectLogFetcher.java:111

            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);
                    if (StringUtils.containsIgnoreCase(errmsg, "not find first log file name")
                        || StringUtils.containsIgnoreCase(errmsg, "purged binary logs")) {
                        // 开始 dump 后,server 位点过期,DUMP 和 DUMP_GTID 两种错误信息
                        throw new ServerLogPurgedException(
                            " errno = " + errno + ", sqlstate = " + sqlstate + " errmsg = " + errmsg);
                    }

                    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. It's may be duplicate slaveId , check instance config");
                    return false;
                } else {
                    // Should not happen.
                    throw new IOException("Unexpected response " + mark + " while fetching binlog: packet #" + netnum
                                          + ", len = " + netlen);
                }
            }

            // if mysql is in semi mode
            if (issemi) {
                // parse semi mark
                int semimark = getUint8(NET_HEADER_SIZE + 1);

View on GitHub (pinned to 87be50e876)

Solutions

  1. Read the errno and errmsg in the exception message to identify the specific MySQL error code.
  2. For errno 1227: re-grant REPLICATION SLAVE, REPLICATION CLIENT privileges.
  3. For errno 1236 with a non-purge message: check MySQL error log for binlog corruption; consider re-synchronizing from current master status.
  4. Verify server_id uniqueness — duplicate server_id values cause the master to disconnect the slave stream.

Example fix

// before — no specific handling
try {
    directLogFetcher.fetch();
} catch (IOException e) {
    // generic handling
}

// after — distinguish replication errors
try {
    directLogFetcher.fetch();
} catch (ServerLogPurgedException e) {
    // re-discover start position (handled by error 402 logic)
} catch (IOException e) {
    // inspect errno in message, retry with backoff or alert
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    directLogFetcher.fetch();
} catch (IOException e) {
    String msg = e.getMessage();
    if (msg.contains("errno = 1227")) {
        // Access denied — privilege issue, do not retry blindly
        throw new ConfigurationException("Replication privilege revoked mid-stream", e);
    } else if (msg.contains("errno = 1236")) {
        // Fatal binlog error — may need position reset
        logger.error("Fatal binlog error from master", e);
    }
    // Other errors: retry with backoff
}

Prevention

When it happens

Trigger: The master replies with errno+sqlstate+errmsg after a DUMP request, but the errmsg is not about purged logs. Common MySQL errors: 1236 (fatal error reading binlog), 1227 (access denied for replication), 13114 (unable to read log event), or ER_* replication failures.

Common situations: The replication user lost REPLICATION SLAVE privilege mid-stream. The master's binlog file is corrupted. A failover occurred and the new master has a different server_id or binlog format. The requested position is beyond the end of the current binlog file. MySQL was upgraded and the binlog format changed.

Related errors


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