alibaba/canal · error · CanalParseException

command : ' + showSql + ' has an error! pls check. you need

Error message

command : ' + showSql + ' has an error! pls check. you need (at least one of) the SUPER,REPLICATION CLIENT privilege(s) for this operation

What it means

findEndPosition() runs `show master status` (or `show binary log status` on MySQL 8.4, or multi-stream variant for PolarDB-X). If the field list is empty, Canal treats it as a privilege failure and throws CanalParseException requesting SUPER / REPLICATION CLIENT, because an empty result means the session cannot see binary log status.

Source

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

    }

    /**
     * 查询当前的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();
            if (CollectionUtils.isEmpty(fields)) {
                throw new CanalParseException(
                    "command : '" + showSql + "' 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)));
            if (isGTIDMode() && fields.size() > 4) {
                endPosition.setGtid(fields.get(4));
            }
            // MariaDB 无法通过`show master status`获取 gtid
            if (mysqlConnection.isMariaDB() && isGTIDMode()) {
                ResultSetPacket gtidPacket = mysqlConnection.query("SELECT @@global.gtid_binlog_pos");
                List<String> gtidFields = gtidPacket.getFieldValues();
                if (!CollectionUtils.isEmpty(gtidFields) && gtidFields.size() > 0) {
                    endPosition.setGtid(gtidFields.get(0));
                }
            }
            return endPosition;
        } catch (IOException e) {
            throw new CanalParseException("command : '" + showSql + "' has an error!", e);
        }

View on GitHub (pinned to 87be50e876)

Solutions

  1. Grant REPLICATION CLIENT (and SUPER where required): `GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';`.
  2. Confirm binary logging is enabled: `SHOW VARIABLES LIKE 'log_bin';` must be ON and `SHOW MASTER STATUS;` returns a row.
  3. On MySQL 8.4+, ensure the atLeastMySQL84() detection is correct so `show binary log status` is used.

Example fix

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;
-- verify
SHOW MASTER STATUS;  -- or SHOW BINARY LOG STATUS; on 8.4
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight master status visibility
ResultSetPacket rs = connection.query(showSql);
if (rs == null || CollectionUtils.isEmpty(rs.getFieldValues())) {
    throw new IllegalStateException("Empty result for " + showSql + "; grant REPLICATION CLIENT and confirm log_bin=ON.");
}

Prevention

When it happens

Trigger: The account cannot view binary log status — `show master status` returns no rows because binary logging is off, or the user lacks REPLICATION CLIENT privilege to see it.

Common situations: Binary logging disabled on the master (log_bin=OFF); canal user missing REPLICATION CLIENT; connecting to a read-only replica without binlog; MySQL 8.4 where the command changed to `show binary log status` but privileges still missing.

Related errors


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