apache/seatunnel · critical · RuntimeException
Can't obtain schema for table %s
Error message
Can't obtain schema for table %s
What it means
After both the information-schema load and the `DESC` fallback, readTableSchema checks that tableChangeMap contains the requested TableId. If not, it throws RuntimeException 'Can't obtain schema for table <id>' — meaning schema was loaded but the target table is absent from the result.
Source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/mysql/utils/MySqlSchema.java:102
try {
tableChangeMap = getTableSchemaByShowCreateTable(jdbc, tableId);
if (tableChangeMap.isEmpty()) {
log.debug("Load schema is empty for table {}", tableId);
}
} catch (Exception e) {
log.debug("Ignore exception when execute `SHOW CREATE TABLE {}` failed", tableId, e);
}
if (tableChangeMap.isEmpty()) {
try {
log.info("Fallback to use `DESC {}` load schema", tableId);
tableChangeMap = getTableSchemaByDescTable(jdbc, tableId);
} catch (SQLException ex) {
throw new SeaTunnelException(
String.format("Failed to read schema for table %s", tableId), ex);
}
}
if (!tableChangeMap.containsKey(tableId)) {
throw new RuntimeException(String.format("Can't obtain schema for table %s", tableId));
}
return tableChangeMap.get(tableId);
}
@VisibleForTesting
public TableChange readTableSchemaByDesc(JdbcConnection jdbc, TableId tableId) {
try {
return getTableSchemaByDescTable(jdbc, tableId).get(tableId);
} catch (SQLException ex) {
throw new SeaTunnelException(
String.format("Failed to read schema for table %s", tableId), ex);
}
}
private Map<TableId, TableChange> getTableSchemaByShowCreateTable(
JdbcConnection jdbc, TableId tableId) throws SQLException {
AtomicReference<String> ddl = new AtomicReference<>();View on GitHub (pinned to cf67b549a7)
Solutions
- Confirm the exact table name/case as MySQL sees it (`SELECT table_schema, table_name FROM information_schema.tables WHERE lower(table_name)=...`)
- Re-check the table exists at job start; recreate or restore it if dropped
- Use fully-qualified, correctly-quoted table names in the SeaTunnel catalog/table config
- Align lower_case_table_names expectations between config and server
Example fix
// before
{"table-names": ["MYDB.MYTABLE"]}
// after
{"table-names": ["mydb.mytable"]} // exact case as in MySQL Defensive patterns
Strategy: validation
Validate before calling
SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema='mydb' AND BINARY table_name='mytable'; // must return exactly one row matching your config
Try / catch
try {
startCdcJob(config);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Can't obtain schema for table")) {
log.error("Schema loaded but table missing from result; verify exact identifier case");
}
} Prevention
- Use exact case-qualified identifiers in table-names
- Avoid DDL (drop/rename) while the job runs
- Reconcile quoted vs unquoted identifiers between config and server catalog
When it happens
Trigger: getTableSchema where getTableSchemaByDescTable succeeded but the returned map does not contain the exact TableId (name/case mismatch) or both loaders returned no schema for it.
Common situations: Case-mismatched database/table identifiers on case-sensitive filesystems; table deleted after job planning; catalog qualifier differences (quoted identifiers) between information schema and DESC output.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Failed to read schema for table ${tableId}
- Unable to find table in relational model: <tableId>
- Unable to find table in relational model: ${tableId}
- Can't obtain schema for table %s
- Encountered change event '{}' at offset {} for table {} whos
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/813a89889c4df9ce.
Report an issue: GitHub.