alibaba/canal · error · CanalParseException
apply failed
Error message
apply failed
What it means
Thrown as CanalParseException by DatabaseTableMeta.applyHistoryOnMemory() when any Throwable occurs while replaying DDL history records from the TSDB into memory. Unlike error 436, this message has NO cause detail — it only says 'apply failed' with the exception attached.
Source
Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/tsdb/DatabaseTableMeta.java:643
// 如果是同一秒内,对比一下history的位点,如果比期望的位点要大,忽略之
if (snapshotPosition.getTimestamp() > rollbackPosition.getTimestamp()) {
continue;
} else if (rollbackPosition.getServerId().equals(snapshotPosition.getServerId())
&& snapshotPosition.compareTo(rollbackPosition) > 0) {
continue;
}
// 记录到内存
if (!memoryTableMeta.apply(snapshotPosition, useSchema, sqlData, null)) {
return false;
}
}
return metaHistoryDOList.size() > 0;
} catch (Throwable e) {
throw new CanalParseException("apply failed", e);
}
}
private String structureSchema(String schema) {
if (schema.startsWith("`") && schema.endsWith("`")) {
return schema;
}
return "`" + schema + "`";
}
private String getFullName(String schema, String table) {
StringBuilder builder = new StringBuilder();
return builder.append(structureSchema(schema))
.append('.')
.append('`')
.append(StringUtils.replace(table, "`", "``"))
.append('`')
.toString();View on GitHub (pinned to 87be50e876)
Solutions
- Examine the attached cause exception (the 'e' parameter) for the real root cause — the message itself is uninformative.
- If NumberFormatException on binlogMasterId, inspect and clean the meta_history table for invalid masterId values.
- If memoryTableMeta.apply() returned false, check if the DDL text in the history record is valid and parseable.
- Clear corrupt history records from the TSDB and trigger a fresh full dump.
Defensive patterns
Strategy: fallback
Try / catch
try {
tableMeta.rollback(position);
} catch (CanalParseException e) {
if (e.getMessage().equals("apply failed")) {
Throwable cause = e.getCause();
// inspect cause: if NumberFormatException on masterId, clean history records
// if DDL parse failure, remove corrupt history entry
}
} Prevention
- Validate TSDB history data integrity periodically.
- Do not manually insert records into the meta_history table.
- Handle null/non-numeric binlogMasterId gracefully in custom DAO implementations.
- Back up TSDB data before maintenance.
When it happens
Trigger: memoryTableMeta.apply() returns false for a history DDL entry, OR an exception is thrown during the loop: metaHistoryDAO.findByTimestamp() fails, Long.valueOf(binlogMasterId) throws NumberFormatException for non-numeric master IDs, or EntryPosition.compareTo() fails.
Common situations: binlogMasterId in the TSDB history table is non-numeric or null (stored as string that fails Long.valueOf); corrupt DDL text in history table; TSDB connection lost during history query; version mismatch in the history record format.
Related errors
- apply to memory is failed
- apply history to db failed caused by : {errorMessage}
- not support for memory
- unknow column : + name
- [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/3a9315198948c06d.
Report an issue: GitHub.