alibaba/canal · error · CanalParseException
column size is not match for table:{},{} vs {}
Error message
column size is not match for table:{},{} vs {} What it means
Thrown from parseOneRow() when the binlog's column count (columnInfo.length) exceeds the cached table metadata's field count (tableMeta.getFields().size()). This means the binlog event references more columns than Canal's metadata believes the table has — a clear sign that a DDL (column addition) happened but the metadata cache was not invalidated or TSDB didn't track it.
Source
Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/LogEventConvert.java:660
// 1. 新增一张临时表,将需要做ddl表的数据全量导入
// 2. 在老表上建立I/U/D的trigger,增量的将数据插入到临时表
// 3. 锁住应用请求,将临时表rename为老表的名字,完成增加字段的操作
// 尝试做一次reload,可能因为ddl没有正确解析,或者使用了类似online ddl的操作
// 因为online ddl没有对应表名的alter语法,所以不会有clear cache的操作
tableMeta = getTableMeta(event.getTable().getDbName(), event.getTable().getTableName(), false, position);// 强制重新获取一次
if (tableMeta == null) {
tableError = true;
if (!filterTableError) {
throw new CanalParseException("not found [" + event.getTable().getDbName() + "."
+ event.getTable().getTableName() + "] in db , pls check!");
}
}
// 在做一次判断
if (tableMeta != null && columnInfo.length > tableMeta.getFields().size()) {
tableError = true;
if (!filterTableError) {
throw new CanalParseException("column size is not match for table:" + tableMeta.getFullName()
+ "," + columnInfo.length + " vs " + tableMeta.getFields().size());
}
}
// } else {
// logger.warn("[" + event.getTable().getDbName() + "." +
// event.getTable().getTableName()
// + "] is no primary key , skip alibaba_rds_row_id column");
}
}
for (int i = 0; i < columnCnt; i++) {
ColumnInfo info = columnInfo[i];
// mysql 5.6开始支持nolob/mininal类型,并不一定记录所有的列,需要进行判断
if (!cols.get(i)) {
continue;
}
if (existRDSNoPrimaryKey && i == columnCnt - 1 && info.type == LogEvent.MYSQL_TYPE_LONGLONG) {View on GitHub (pinned to 87be50e876)
Solutions
- Enable TSDB: canal.instance.tsdb.enable=true and canal.instance.tsdb.dir=../conf/tsdb for persistent DDL history.
- If filterQueryDdl=true, either disable it or manually trigger a metadata refresh after known schema changes.
- Call tableMetaCache.clearTableMeta(schema, table) or restart Canal to force a full metadata reload.
- Verify the canal user can see the DDL events in the binlog (no binlog filtering on the MySQL side).
Example fix
# before — no TSDB, DDL filtered canal.instance.tsdb.enable=false canal.instance.filter.query.ddl=true # after — TSDB enabled to track DDL history canal.instance.tsdb.enable=true canal.instance.tsdb.dir=../conf/tsdb canal.instance.filter.query.ddl=false
Defensive patterns
Strategy: fallback
Try / catch
try {
// parseOneRow with column check
parseRowsEventForTableMeta(event);
} catch (CanalParseException e) {
if (e.getMessage().contains("column size is not match")) {
// Stale metadata — force a full cache invalidation and retry
tableMetaCache.clearTableMeta(schema, table);
logger.warn("Column mismatch detected, cache cleared for {}.{}, retrying", schema, table);
// The next event will reload fresh metadata
}
} Prevention
- Enable TSDB (canal.instance.tsdb.enable=true) to track DDL history and avoid stale metadata.
- Do not set canal.instance.filter.query.ddl=true when DML events for the same tables are expected.
- After manual schema changes, restart Canal or trigger a metadata cache flush.
When it happens
Trigger: After the forced reload in parseOneRow(), tableMeta is non-null but columnInfo.length > tableMeta.getFields().size(). The binlog was written with N columns but the current metadata only knows about N-k columns. This happens when ALTER TABLE ADD COLUMN occurred but Canal's DDL cache wasn't updated (the DDL event was filtered, missed, or came from a different connection).
Common situations: An ALTER TABLE added columns but Canal filtered out the DDL event (filterQueryDdl=true). The DDL was executed on a different schema name or through a stored procedure that Canal's parser didn't capture. TSDB is disabled so no historical DDL tracking exists. A replication filter on the MySQL side excluded the DDL but not the subsequent DML.
Related errors
- unknow column : + name
- MySQL8.0 unmatch column metadata & pls submit issue , table
- fetch failed by table meta:{}
- can't find init table meta for {} with position : {}
- [fixed timestamp] can't found begin/commit position before w
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/f471d3ad406e74ea.
Report an issue: GitHub.