alibaba/canal · error · IllegalStateException

unexpected binlog format query result: + rs.getFieldValues()

Error message

unexpected binlog format query result: + rs.getFieldValues()

What it means

loadBinlogFormat() runs `show variables like 'binlog_format'` and expects exactly 2 field values (variable name + value). If the result set is null or does not have exactly 2 columns, Canal throws IllegalStateException because it cannot safely determine the binlog format — continuing with an unknown format could misparse row events. This is a hard stop to force a connection teardown.

Source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlConnection.java:528

        }
    }

    /**
     * 获取一下binlog format格式
     */
    private void loadBinlogFormat() {
        ResultSetPacket rs = null;
        try {
            rs = query("show variables like 'binlog_format'");
        } catch (IOException e) {
            throw new CanalParseException(e);
        }

        List<String> columnValues = rs.getFieldValues();
        if (columnValues == null || columnValues.size() != 2) {
            logger.warn(
                "unexpected binlog format query result, this may cause unexpected result, so throw exception to request network to io shutdown.");
            throw new IllegalStateException("unexpected binlog format query result:" + rs.getFieldValues());
        }

        binlogFormat = BinlogFormat.valuesOf(columnValues.get(1));
        if (binlogFormat == null) {
            throw new IllegalStateException("unexpected binlog format query result:" + rs.getFieldValues());
        }
    }

    /**
     * 获取一下binlog image格式
     */
    private void loadBinlogImage() {
        ResultSetPacket rs = null;
        try {
            rs = query("show variables like 'binlog_row_image'");
        } catch (IOException e) {
            throw new CanalParseException(e);
        }

View on GitHub (pinned to 87be50e876)

Solutions

  1. Grant the account permission to read variables (REPLICATION CLIENT / PROCESS / SELECT on mysql, or SUPER as appropriate).
  2. Manually run `show variables like 'binlog_format'` as the canal user to confirm it returns one row with two columns.
  3. Ensure the target is a real MySQL/MariaDB master with binary logging enabled (log_bin=ON, binlog_format set to ROW).
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight check the user can read binlog_format
ResultSetPacket rs = connection.query("show variables like 'binlog_format'");
List<String> vals = rs.getFieldValues();
if (vals == null || vals.size() != 2) {
    throw new IllegalStateException(
        "Cannot read binlog_format (got " + vals + "). Grant REPLICATION CLIENT/PROCESS to the canal user.");
}

Prevention

When it happens

Trigger: The query returns zero rows (binlog_format variable not exposed to the session), an unexpected number of columns, or a null field list. This happens on privilege-restricted accounts or unusual server configurations where the variable is hidden.

Common situations: The canal DB user lacks permission to read session/global variables; connecting to a read-replica or proxy that strips variable queries; a non-MySQL-compatible server that does not expose binlog_format.

Related errors


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