apache/seatunnel · warning
[FileSchemaEvolution] DROP event references unknown column
Error message
[FileSchemaEvolution] DROP event references unknown column '{}' — ignored What it means
A WARN from AbstractWriteStrategy.updateSinkColumnNames during schema evolution: an AlterTableDropColumnEvent named a column that does not exist in the current sink schema (comparison is case-insensitive), so the DROP is ignored and the file schema is left unchanged. This prevents index-out-of-bounds or silent corruption from stale/mismatched CDC events.
Solutions
- Verify the column actually exists in the sink schema (check the SeaTunnel catalog table definition)
- If replaying CDC, start from a binlog position consistent with the current sink schema
- Align the sink schema with the source (add the column, or rebuild the target table) so subsequent DROP events apply
- If the drop was expected to be ignored, this warn is safe to disregard
Defensive patterns
Strategy: validation
Validate before calling
// before applying DROP events, check membership (case-insensitive):
boolean exists = sinkColumnNames.stream()
.anyMatch(c -> c.equalsIgnoreCase(dropColumn));
if (!exists) log.warn("DROP ignored: column {} not in sink schema", dropColumn); Prevention
- Keep sink schema in sync with source table before enabling schema evolution
- Start CDC from a binlog position consistent with the current sink schema
- Avoid two pipelines dropping the same column concurrently
- If the column is projected out of the sink, expect and ignore this warn
When it happens
Trigger: applySchemaChange -> updateSinkColumnNames receives a DROP event whose column was already dropped upstream, was never part of the sink projection (source selects a subset), or differs due to case handled correctly but still absent from sinkColumnNames.
Common situations: Replaying CDC from an earlier binlog position re-sending old DROP events; multiple upstream pipelines both dropping the same column; source table renamed/recreated while SeaTunnel job ran; schema mismatch between source snapshot and event stream.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Failed to resolve schemaChangeEvent, just skip.
- Interrupted while dispatching PostgreSQL relation change for
- INVALID_SCHEMA_STRUCTURE
- PostgreSQL-CDC schema evolution requires…
- Received AlterTableEvent but schema_evolution_enabled=false…
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/0a827a17232e0a5d.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sink/writer/AbstractWriteStrategy.java:358
boolean alreadyPresent =
sinkColumnNames.stream().anyMatch(c -> c.equalsIgnoreCase(newCol));
if (!alreadyPresent) {
if (e.isFirst()) {
sinkColumnNames.add(0, newCol);
} else if (e.getAfterColumn() != null) {
int pos = indexOfIgnoreCase(sinkColumnNames, e.getAfterColumn());
sinkColumnNames.add(pos >= 0 ? pos + 1 : sinkColumnNames.size(), newCol);
} else {
sinkColumnNames.add(newCol);
}
}
} else if (event instanceof AlterTableDropColumnEvent) {
// Case-insensitive removal: CDC sources may send column names in any case
String toDrop = ((AlterTableDropColumnEvent) event).getColumn();
boolean removed = sinkColumnNames.removeIf(c -> c.equalsIgnoreCase(toDrop));
if (!removed) {
log.warn(
"[FileSchemaEvolution] DROP event references unknown column '{}' — ignored",
toDrop);
}
} else if (event instanceof AlterTableChangeColumnEvent) {
// RENAME (and optional MOVE): remove old name, insert new name at target position.
// AlterTableChangeColumnEvent covers MySQL's CHANGE COLUMN which can rename and
// reorder in one statement. Both the rename and the position change are applied.
AlterTableChangeColumnEvent e = (AlterTableChangeColumnEvent) event;
int idx = indexOfIgnoreCase(sinkColumnNames, e.getOldColumn());
if (idx >= 0) {
sinkColumnNames.remove(idx);
String newName = e.getColumn().getName();
if (e.isFirst()) {
sinkColumnNames.add(0, newName);
} else if (e.getAfterColumn() != null) {
int afterIdx = indexOfIgnoreCase(sinkColumnNames, e.getAfterColumn());
sinkColumnNames.add(
afterIdx >= 0 ? afterIdx + 1 : sinkColumnNames.size(), newName);
} else {View on GitHub (pinned to cf67b549a7)