alibaba/canal · error · CanalParseException

command : 'show binlog events limit 1' has an error!

Error message

command : 'show binlog events limit 1' has an error!

What it means

Thrown from the catch(IOException) block of findStartPosition() when the 'show binlog events limit 1' query itself fails at the transport/protocol level. Unlike error 400 (which fires on an empty-but-successful result), this wraps the underlying IOException — the MySQL server rejected the query, the connection dropped, or the socket read failed before any result packet arrived.

Source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java:718

    /**
     * 查询当前的binlog位置
     */
    private EntryPosition findStartPosition(MysqlConnection mysqlConnection) {
        try {
            String showSql = "show binlog events limit 1";
            if (multiStreamEnable) {
                showSql = "show binlog events with " + destination + " limit 1";
            }
            ResultSetPacket packet = mysqlConnection.query(showSql);
            List<String> fields = packet.getFieldValues();
            if (CollectionUtils.isEmpty(fields)) {
                throw new CanalParseException(
                        "command : 'show binlog events limit 1' has an error! pls check. you need (at least one of) the SUPER,REPLICATION CLIENT privilege(s) for this operation");
            }
            EntryPosition endPosition = new EntryPosition(fields.get(0), Long.valueOf(fields.get(1)));
            return endPosition;
        } catch (IOException e) {
            throw new CanalParseException("command : 'show binlog events limit 1' has an error!", e);
        }

    }

    /**
     * 查询当前的slave视图的binlog位置
     */
    @SuppressWarnings("unused")
    private SlaveEntryPosition findSlavePosition(MysqlConnection mysqlConnection) {
        try {
            String showSql = "show slave status";
            if (mysqlConnection.atLeastMySQL84()) {
                // 兼容mysql 8.4
                showSql = "show replica status";
            }
            ResultSetPacket packet = mysqlConnection.query(showSql);
            List<FieldPacket> names = packet.getFieldDescriptors();
            List<String> fields = packet.getFieldValues();

View on GitHub (pinned to 87be50e876)

Solutions

  1. Verify log_bin is ON: run 'SHOW VARIABLES LIKE "log_bin";' on the MySQL server.
  2. Check network stability between the canal instance and MySQL host (firewall idle timeout, NAT, proxy).
  3. Increase the socket read timeout in the canal JDBC URL (e.g. connectTimeout / socketTimeout parameters).
  4. Confirm the MySQL server is reachable and not under extreme load at startup time.

Example fix

# before
canal.instance.master.address=10.0.0.5:3306

# after — add socket timeouts to the JDBC URL
canal.instance.master.address=10.0.0.5:3306
canal.instance.master.jdbc.url=jdbc:mysql://10.0.0.5:3306?connectTimeout=10000&socketTimeout=60000
Defensive patterns

Strategy: retry

Validate before calling

// Check that log_bin is enabled before starting
ResultSetPacket rs = mysqlConnection.query("SHOW VARIABLES LIKE 'log_bin'");
String logBin = rs.getFieldValues().get(1);
if (!"ON".equalsIgnoreCase(logBin)) {
    throw new IllegalStateException("MySQL binlog is not enabled (log_bin=OFF)");
}

Try / catch

int maxRetries = 3;
for (int attempt = 0; attempt < maxRetries; attempt++) {
    try {
        EntryPosition pos = findStartPosition(mysqlConnection);
        break;
    } catch (CanalParseException e) {
        if (e.getCause() instanceof IOException && attempt < maxRetries - 1) {
            Thread.sleep((attempt + 1) * 2000L);
            mysqlConnection.reconnect();
            continue;
        }
        throw e;
    }
}

Prevention

When it happens

Trigger: mysqlConnection.query(showSql) throws an IOException during the binlog-events query. Causes include: the server actively denies the command (returns an error packet that the driver surfaces as IOException), the TCP connection was reset mid-query, the connection timed out, or the MySQL process was killed.

Common situations: The MySQL server has binlog disabled (log_bin=OFF) so the command fails. A firewall or load balancer killed the idle connection before the query ran. The MySQL server restarted between connection-establishment and position-discovery. Network latency caused a socket read timeout on a large binlog.

Related errors


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