alibaba/canal · error · IllegalArgumentException
!! Don't know how to handle column type=%d meta=%d (%04X)
Error message
!! Don't know how to handle column type=%d meta=%d (%04X)
What it means
Thrown by RowsLogBuffer.fetchValue when decoding a column declared MYSQL_TYPE_STRING whose metadata (meta) is >= 256. The code splits meta into byte0 (high) and byte1 (low); if byte0 has the 0x30 bits set (indicating a real STRING/ENUM/SET) but byte0 itself is none of MYSQL_TYPE_SET, MYSQL_TYPE_ENUM, or MYSQL_TYPE_STRING, the encoded type is unrecognized. This is a defensive guard for a STRING-type column whose real-type byte doesn't map to any known MySQL string family, as described in MySQL bug #37426.
Source
Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/RowsLogBuffer.java:298
if (type == LogEvent.MYSQL_TYPE_STRING) {
if (meta >= 256) {
int byte0 = meta >> 8;
int byte1 = meta & 0xff;
if ((byte0 & 0x30) != 0x30) {
/* a long CHAR() field: see #37426 */
len = byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
type = byte0 | 0x30;
} else {
switch (byte0) {
case LogEvent.MYSQL_TYPE_SET:
case LogEvent.MYSQL_TYPE_ENUM:
case LogEvent.MYSQL_TYPE_STRING:
type = byte0;
len = byte1;
break;
default:
throw new IllegalArgumentException(String
.format("!! Don't know how to handle column type=%d meta=%d (%04X)", type, meta, meta));
}
}
} else {
len = meta;
}
}
switch (type) {
case LogEvent.MYSQL_TYPE_LONG: {
// XXX: How to check signed / unsigned?
// value = unsigned ? Long.valueOf(buffer.getUint32()) :
// Integer.valueOf(buffer.getInt32());
value = valueOf(buffer.getInt32());
javaType = Types.INTEGER;
length = 4;
break;
}
View on GitHub (pinned to 87be50e876)
Solutions
- Upgrade Canal to match the master's MySQL version so all real-type bytes are recognized.
- Verify the column DDL on the master matches what Canal's table-map cache expects (re-snapshot if schema drifted).
- If the column is genuinely new, add its type constant to the switch in RowsLogBuffer.fetchValue and map it to a sensible java.sql.Types.
- Filter the offending table out of replication (canal.instance.filter.regex) until Canal supports it.
Example fix
// before
case LogEvent.MYSQL_TYPE_SET:
case LogEvent.MYSQL_TYPE_ENUM:
case LogEvent.MYSQL_TYPE_STRING:
type = byte0;
len = byte1;
break;
default:
throw new IllegalArgumentException(String.format("!! Don't know how to handle column type=%d meta=%d (%04X)", type, meta, meta));
// after: treat unknown real-type byte as plain STRING instead of aborting
default:
logger.warn("Unknown STRING real-type byte {} (meta={}), treating as STRING", byte0, meta);
type = LogEvent.MYSQL_TYPE_STRING;
len = byte1; Defensive patterns
Strategy: validation
Validate before calling
// Before relying on fetchValue, validate the column type/meta against a known-good schema
boolean isKnownStringSubtype(int byte0) {
return byte0 == LogEvent.MYSQL_TYPE_SET
|| byte0 == LogEvent.MYSQL_TYPE_ENUM
|| byte0 == LogEvent.MYSQL_TYPE_STRING;
} Try / catch
try {
buffer.fetchValue(name, index, type, meta, isBinary);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("!! Don't know how to handle column type")) {
logger.error("Unsupported STRING column type={}/meta={} in table {}, skipping event", type, meta, tableId);
// optionally skip or null the column value
} else throw e;
} Prevention
- Keep Canal and master MySQL versions aligned so table-map type bytes are all recognized.
- Avoid exotic STRING sub-types in replicated schemas or filter their tables.
- Pin the source schema and re-snapshot Canal's table-map cache after DDL changes.
When it happens
Trigger: A Table_map_event advertises a column of type MYSQL_TYPE_STRING with a meta word whose high byte carries a type the switch doesn't enumerate. Produced by MySQL forks adding new string-like subtypes, or by binlog corruption altering the meta field.
Common situations: Replicating from a MySQL/MariaDB version newer than what Canal was built against; a corrupted Table_map event; a custom column type plugin on the master.
Related errors
- !! Unknown Bit len =
- !! Unknown ENUM packlen =
- !! Unknown Set len =
- !! Unknown BLOB packlen =
- !! Unknown JSON packlen =
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/7318ebacf1cedbfe.
Report an issue: GitHub.