alibaba/canal · error · CanalParseException
fetch failed by table meta:{}
Error message
fetch failed by table meta:{} What it means
Thrown from the TSDB code path of TableMetaCache.getTableMeta() when an IOException occurs during the 'show create table' query that follows a TSDB cache miss. Unlike error 414 (which uses the Guava cache loader path), this is the explicit TSDB synchronization path: Canal found no tableMeta in TSDB, acquires a synchronized lock, retries the query after reconnect, and if that still fails, wraps the IOException in this CanalParseException.
Source
Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/TableMetaCache.java:213
ResultSetPacket packet = null;
try {
packet = connection.query("show create table " + fullName);
} catch (Exception e) {
// 尝试做一次retry操作
connection.reconnect();
packet = connection.query("show create table " + fullName);
}
String createDDL = null;
if (packet.getFieldValues().size() > 0) {
createDDL = packet.getFieldValues().get(1);
}
// 强制覆盖掉内存值
tableMetaTSDB.apply(position, schema, createDDL, "first");
tableMeta = tableMetaTSDB.find(schema, table);
}
} catch (IOException e) {
throw new CanalParseException("fetch failed by table meta:" + fullName, e);
}
}
return tableMeta;
} else {
String fullName = getFullName(schema, table);
if (!useCache) {
// tableMetaCache.invalidate(getFullName(schema, table));
tableMetaCache.invalidate(fullName);
}
// return tableMetaCache.getUnchecked(getFullName(schema, table));
return tableMetaCache.getUnchecked(fullName);
}
}
public void clearTableMeta(String schema, String table) {
if (tableMetaTSDB != null) {
// tsdb不需要做,会基于ddl sql自动清理
} else {View on GitHub (pinned to 87be50e876)
Solutions
- Verify MySQL connectivity and connection pool health (the reconnect path suggests intermittent connection loss).
- Increase the connection idle timeout / wait_timeout on MySQL to prevent premature disconnects.
- Check if the table exists: run 'show create table schema.table' manually with the canal user.
- If using a connection proxy, ensure it doesn't kill long-lived connections during metadata queries.
Example fix
# before # (no connection timeout configuration) # after — configure connection persistence canal.instance.master.jdbc.url=jdbc:mysql://host:3306?autoReconnect=true&connectTimeout=10000&socketTimeout=30000&tcpKeepAlive=true
Defensive patterns
Strategy: retry
Try / catch
try {
TableMeta meta = tableMetaCache.getTableMeta(schema, table, useCache, position);
} catch (CanalParseException e) {
if (e.getMessage().contains("fetch failed by table meta")) {
// TSDB path failed — wait and retry with a fresh connection
Thread.sleep(5000L);
connection.reconnect();
// Retry once more
meta = tableMetaCache.getTableMeta(schema, table, false, position);
}
} Prevention
- Use JDBC URL with tcpKeepAlive=true and autoReconnect=true to prevent silent connection drops.
- Increase MySQL wait_timeout to exceed Canal's longest idle period between metadata queries.
- Monitor connection pool health and alert on reconnect events.
When it happens
Trigger: getTableMeta(schema, table, useCache, position) is called with tableMetaTSDB != null (TSDB enabled). tableMetaTSDB.find() returns null, so Canal enters the synchronized block and runs 'show create table'. If the first query throws, it reconnects and retries; if the retry throws IOException, this exception fires.
Common situations: TSDB is enabled but the MySQL connection dropped during metadata synchronization. The connection was closed by a server-side timeout between the TSDB lookup and the 'show create table' query. A failover occurred during TSDB initialization. The table was dropped between the binlog event and the TSDB sync attempt.
Related errors
- column size is not match for table:{},{} vs {}
- fetch table meta failed. table: {}
- Unable to unwrap {} to com.mysql.jdbc.ConnectionImpl
- Get null field:{}#io
- connect failure
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/329e127ecf954dd5.
Report an issue: GitHub.