alibaba/canal · error · CanalParseException

command : show variables like 'server_id' has an error!

Error message

command : show variables like 'server_id' has an error!

What it means

findServerId()'s catch (IOException) wraps any I/O failure of the `show variables like 'server_id'` query in CanalParseException. Unlike error 396 (empty result = privilege), this fires when the query itself fails at the transport/protocol level — the connection broke, timed out, or the server returned a protocol error.

Source

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

            }
        }
        // 找不到
        return null;
    }

    /**
     * 查询当前db的serverId信息
     */
    private Long findServerId(MysqlConnection mysqlConnection) {
        try {
            ResultSetPacket packet = mysqlConnection.query("show variables like 'server_id'");
            List<String> fields = packet.getFieldValues();
            if (CollectionUtils.isEmpty(fields)) {
                throw new CanalParseException("command : show variables like 'server_id' has an error! pls check. you need (at least one of) the SUPER,REPLICATION CLIENT privilege(s) for this operation");
            }
            return Long.valueOf(fields.get(1));
        } catch (IOException e) {
            throw new CanalParseException("command : show variables like 'server_id' has an error!", e);
        }
    }

    /**
     * 查询当前的binlog位置
     */
    private EntryPosition findEndPosition(MysqlConnection mysqlConnection) {
        String showSql = "show master status";
        try {
            if (mysqlConnection.atLeastMySQL84()) {
                // 8.4新语法
                showSql = "show binary log status";
            } else if (multiStreamEnable) {
                // 兼容polardb-x的多流binlog
                showSql = "show master status with " + destination;
            }
            ResultSetPacket packet = mysqlConnection.query(showSql);
            List<String> fields = packet.getFieldValues();

View on GitHub (pinned to 87be50e876)

Solutions

  1. Check network connectivity and latency between canal and the MySQL master.
  2. Increase connection/socket timeout (defaultConnectionTimeoutInSeconds) if the query is timing out.
  3. Ensure the connection is alive before the query; canal's reconnect logic should retry — verify retry/HA config.
  4. Inspect the wrapped IOException cause for the precise failure (SocketTimeoutException, Connection reset, etc.).
Defensive patterns

Strategy: retry

Validate before calling

// Verify connectivity before the metadata query
if (!connection.isConnected()) {
    connection.reconnect();
}

Try / catch

try {
    return findServerId(mysqlConnection);
} catch (CanalParseException e) {
    if (e.getCause() instanceof IOException) {
        logger.warn("Transient IO error reading server_id, will reconnect and retry once", e);
        mysqlConnection.reconnect();
        return findServerId(mysqlConnection); // single retry
    }
    throw e;
}

Prevention

When it happens

Trigger: The query throws IOException — network drop, connection closed by server, socket timeout, or an authentication/protocol error mid-query.

Common situations: Transient network failure to the master; connection idle-timed out (wait_timeout); server restarted mid-session; firewall killed the connection; SSL handshake failure surfacing as IO error.

Related errors


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