{"record":{"id":"9e06642928e7fae4","repo":"apache/iceberg","slug":"cannot-apply-unknown-table-change-9e0664","errorCode":null,"errorMessage":"Cannot apply unknown table change: ","messagePattern":"Cannot apply unknown table change: ","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java","lineNumber":149,"sourceCode":"      } else if (change instanceof TableChange.DropColumn) {\n        TableChange.DropColumn dropColumn = (TableChange.DropColumn) change;\n        pendingUpdate.deleteColumn(dropColumn.getColumnName());\n      } else if (change instanceof TableChange.AddWatermark) {\n        throw new UnsupportedOperationException(\"Unsupported table change: AddWatermark.\");\n      } else if (change instanceof TableChange.ModifyWatermark) {\n        throw new UnsupportedOperationException(\"Unsupported table change: ModifyWatermark.\");\n      } else if (change instanceof TableChange.DropWatermark) {\n        throw new UnsupportedOperationException(\"Unsupported table change: DropWatermark.\");\n      } else if (change instanceof TableChange.AddUniqueConstraint) {\n        TableChange.AddUniqueConstraint addPk = (TableChange.AddUniqueConstraint) change;\n        applyUniqueConstraint(pendingUpdate, addPk.getConstraint());\n      } else if (change instanceof TableChange.ModifyUniqueConstraint) {\n        TableChange.ModifyUniqueConstraint modifyPk = (TableChange.ModifyUniqueConstraint) change;\n        applyUniqueConstraint(pendingUpdate, modifyPk.getNewConstraint());\n      } else if (change instanceof TableChange.DropConstraint) {\n        throw new UnsupportedOperationException(\"Unsupported table change: DropConstraint.\");\n      } else {\n        throw new UnsupportedOperationException(\"Cannot apply unknown table change: \" + change);\n      }\n    }\n  }\n\n  private static void applyAddColumn(UpdateSchema pendingUpdate, TableChange.AddColumn addColumn) {\n    Column flinkColumn = addColumn.getColumn();\n    Preconditions.checkArgument(\n        FlinkCompatibilityUtil.isPhysicalColumn(flinkColumn),\n        \"Unsupported table change: Adding computed column %s.\",\n        flinkColumn.getName());\n\n    Type icebergType = FlinkSchemaUtil.convert(flinkColumn.getDataType().getLogicalType());\n\n    if (flinkColumn.getDataType().getLogicalType().isNullable()) {\n      pendingUpdate.addColumn(\n          flinkColumn.getName(), icebergType, flinkColumn.getComment().orElse(null));\n    } else {\n      pendingUpdate.addRequiredColumn(","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java#L131-L167","documentation":"The default branch of applySchemaChanges throws this when a TableChange instance is not one of the recognized change types (add/modify/rename/drop column, unique-constraint changes, etc.). It indicates an unknown or newly introduced Flink TableChange subtype reached an older/exhaustive switch that does not handle it.","triggerScenarios":"Passing a TableChange subtype not handled by FlinkAlterTableUtil (e.g. a change type added in a newer Flink version or a custom TableChange) into catalog.alterTable / applySchemaChanges.","commonSituations":"Flink/Iceberg version skew where the Flink planner emits new change types; custom catalog wrappers forwarding unfiltered change lists; typos in change handling code.","solutions":["Upgrade iceberg-flink-runtime to a version matching your Flink version so all change types are handled","Log and inspect the change's class name to identify the unhandled type","Pre-filter the TableChange list and reject unsupported types before calling applySchemaChanges"],"exampleFix":"// before\nUnsupportedOperationException: Cannot apply unknown table change: ...\n// after\nif (!(change instanceof TableChange.AddColumn\n    || change instanceof TableChange.ModifyColumn)) {\n  throw new IllegalArgumentException(\"Unsupported change: \" + change.getClass().getName());\n}","handlingStrategy":"type-guard","validationCode":"Set<Class<?>> supported = Set.of(TableChange.AddColumn.class, TableChange.ModifyColumn.class, TableChange.RenameColumn.class, TableChange.DropColumn.class, TableChange.AddUniqueConstraint.class, TableChange.ModifyUniqueConstraint.class);\nboolean ok = changes.stream().allMatch(c -> supported.contains(c.getClass()));\nif (!ok) throw new IllegalArgumentException(\"Change list contains unsupported types\");","typeGuard":"static boolean isKnownSchemaChange(TableChange c) {\n  return c instanceof TableChange.AddColumn || c instanceof TableChange.ModifyColumn\n      || c instanceof TableChange.RenameColumn || c instanceof TableChange.DropColumn\n      || c instanceof TableChange.ModifyColumnPosition || c instanceof TableChange.AddUniqueConstraint\n      || c instanceof TableChange.ModifyUniqueConstraint;\n}","tryCatchPattern":"try { FlinkAlterTableUtil.applySchemaChanges(update, changes); }\ncatch (UnsupportedOperationException e) {\n  if (e.getMessage().startsWith(\"Cannot apply unknown table change\")) { log.warn(\"Unhandled change type; upgrade runtime\", e); }\n  throw e;\n}","preventionTips":["Keep iceberg-flink-runtime and Flink versions aligned","Pre-filter change lists before dispatching to schema-update utilities","Pin exact versions rather than floating ranges"],"tags":["flink","iceberg","unknown-type","schema-change"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}