alibaba/canal · error · CanalParseException
parse row data failed.
Error message
parse row data failed.
What it means
Thrown from the catch(Exception) block of parseRowsEvent() — it is the generic catch-all wrapping any non-CanalParse exception that occurs during row data parsing. The original exception is attached as the cause. This covers charset decoding failures, RowsLogBuffer underflows, NumberFormatException on numeric columns, and other unexpected data-level errors.
Source
Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/LogEventConvert.java:599
}
TableMapLogEvent table = event.getTable();
Header header = createHeader(event.getHeader(),
table.getDbName(),
table.getTableName(),
eventType,
rowsCount);
RowChange rowChange = rowChangeBuider.build();
if (tableError) {
Entry entry = createEntry(header, EntryType.ROWDATA, ByteString.EMPTY);
logger.warn("table parser error : {}storeValue: {}", entry.toString(), rowChange.toString());
return null;
} else {
Entry entry = createEntry(header, EntryType.ROWDATA, rowChange.toByteString());
return entry;
}
} catch (Exception e) {
throw new CanalParseException("parse row data failed.", e);
}
}
private EntryPosition createPosition(LogHeader logHeader) {
return new EntryPosition(logHeader.getLogFileName(), logHeader.getLogPos() - logHeader.getEventLen(), // startPos
logHeader.getWhen() * 1000L,
logHeader.getServerId()); // 记录到秒
}
private boolean parseOneRow(RowData.Builder rowDataBuilder, RowsLogEvent event, RowsLogBuffer buffer, BitSet cols,
boolean isAfter, TableMeta tableMeta) throws UnsupportedEncodingException {
int columnCnt = event.getTable().getColumnCnt();
ColumnInfo[] columnInfo = event.getTable().getColumnInfo();
// mysql8.0针对set @@global.binlog_row_metadata='FULL' 可以记录部分的metadata信息
boolean existOptionalMetaData = event.getTable().isExistOptionalMetaData();
boolean tableError = false;
// check table fileds count,只能处理加字段
boolean existRDSNoPrimaryKey = false;View on GitHub (pinned to 87be50e876)
Solutions
- Examine the cause exception (e.getCause()) in the CanalParseException to identify the specific parsing failure.
- Verify canal.instance.charset matches the database character set (commonly UTF-8).
- If caused by column mismatches, enable TSDB (canal.instance.tsdb.enable=true) for accurate historical DDL tracking.
- Enable filterTableError=true if the root cause is a stale table metadata mismatch.
Example fix
# before canal.instance.charset=UTF-8 canal.instance.tsdb.enable=false # after canal.instance.charset=utf8mb4 canal.instance.tsdb.enable=true
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify charset configuration matches the database before starting
ResultSetPacket rs = mysqlConnection.query("SHOW VARIABLES LIKE 'character_set_database'");
String dbCharset = rs.getFieldValues().get(1);
if (!dbCharset.equalsIgnoreCase(configuredCharset)) {
logger.warn("Charset mismatch: canal={}, db={}, row parsing may fail", configuredCharset, dbCharset);
} Try / catch
try {
Entry entry = parseRowsEvent(event);
} catch (CanalParseException e) {
Throwable cause = e.getCause();
logger.error("Row parsing failed at position {}, cause: {}",
event.getHeader().getLogPos(), cause != null ? cause.getMessage() : "unknown", e);
// Depending on cause type, skip the event or retry after metadata refresh
} Prevention
- Match canal.instance.charset to the database's character_set_database value.
- Enable TSDB for accurate column metadata to avoid parse mismatches.
- Monitor the cause exception chain to distinguish charset issues from buffer underflows.
When it happens
Trigger: Any exception during the row-parsing loop (parseOneRow calls, buffer reads, column building) that is not caught locally bubbles up to the try/catch in parseRowsEvent(). The cause exception reveals the specific failure: UnsupportedEncodingException, IndexOutOfBoundsException from buffer underflow, or data type conversion errors.
Common situations: The canal.instance.charset setting doesn't match the actual table character set, causing decoding errors. A JSON/BLOB column contains data that overflows the expected buffer. A column type in the binlog doesn't match the table metadata (DDL changed columns but cache wasn't refreshed). Network corruption produced a truncated event.
Related errors
- Invalid charset id: {}
- No such method: '{}' @ {}
- No such field: '{}' @ {}
- Unable to unwrap {} to com.mysql.jdbc.ConnectionImpl
- Get null field:{}#io
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/9ac02677e3d8f3f8.
Report an issue: GitHub.