alibaba/canal · error · IllegalArgumentException
!! Unknown ENUM packlen =
Error message
!! Unknown ENUM packlen =
What it means
Thrown while decoding a MYSQL_TYPE_ENUM column. ENUM values are stored as a packed integer of 1 byte (enum <= 255 values) or 2 bytes. The switch only handles len 1 and 2; any other length is impossible for a valid MySQL ENUM and indicates corrupt table-map metadata. The comment notes MYSQL_TYPE_ENUM is internal-only and should not appear in a binlog in modern MySQL, so hitting this also implies a legacy or forked event stream.
Source
Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/RowsLogBuffer.java:859
javaType = Types.VARCHAR; // Types.INTEGER;
length = 1;
break;
}
case LogEvent.MYSQL_TYPE_ENUM: {
final int int32;
/*
* log_event.h : This enumeration value is only used internally and cannot exist
* in a binlog.
*/
switch (len) {
case 1:
int32 = buffer.getUint8();
break;
case 2:
int32 = buffer.getUint16();
break;
default:
throw new IllegalArgumentException("!! Unknown ENUM packlen = " + len);
}
// logger.warn("MYSQL_TYPE_ENUM : This enumeration value is "
// + "only used internally and cannot exist in a binlog!");
value = valueOf(int32);
javaType = Types.INTEGER;
length = len;
break;
}
case LogEvent.MYSQL_TYPE_SET: {
final int nbits = (meta & 0xFF) * 8;
len = (nbits + 7) / 8;
if (nbits > 1) {
// byte[] bits = new byte[len];
// buffer.fillBytes(bits, 0, len);
// 转化为unsign long
switch (len) {
case 1:
value = buffer.getUint8();
View on GitHub (pinned to 87be50e876)
Solutions
- Confirm the master MySQL version; ENUM in binlogs typically arrives as MYSQL_TYPE_STRING in modern versions.
- Inspect the Table_map event with mysqlbinlog --hexdump to verify the column metadata.
- Upgrade Canal to a build that handles the master's encoding.
- Filter the table if the ENUM column is not required downstream.
Defensive patterns
Strategy: validation
Validate before calling
boolean isValidEnumPacklen(int len) {
return len == 1 || len == 2;
} Try / catch
try {
buffer.fetchValue(name, index, type, meta, isBinary);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("!! Unknown ENUM packlen")) {
logger.warn("Corrupt ENUM packlen={} in tableId={}, skipping column", len, tableId);
} else throw e;
} Prevention
- Modern MySQL stores ENUM as MYSQL_TYPE_STRING; if you see MYSQL_TYPE_ENUM in the binlog, suspect an old or forked source.
- Validate the binlog with mysqlbinlog --hexdump when ENUM errors appear.
When it happens
Trigger: A Table_map_event declares ENUM with a storage length other than 1 or 2 bytes, or an event stream from an old MySQL that still writes MYSQL_TYPE_ENUM into the binlog.
Common situations: Replicating from a very old MySQL 5.0/5.1 stream; binlog corruption; a MySQL fork that reuses the ENUM type code differently.
Related errors
- !! Don't know how to handle column type=%d meta=%d (%04X)
- !! Unknown Bit len =
- !! Unknown Set len =
- !! Unknown BLOB packlen =
- !! Unknown JSON packlen =
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/aed18b0bc6d9ae30.
Report an issue: GitHub.