{"record":{"id":"aebe520a5cdadad5","repo":"apache/iceberg","slug":"unknown-transform-s-is-not-supported","errorCode":null,"errorMessage":"Unknown transform %s is not supported","messagePattern":"Unknown transform (.+?) is not supported","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/transforms/PartitionSpecVisitor.java","lineNumber":89,"sourceCode":"\n  default T day(String sourceName, int sourceId) {\n    throw new UnsupportedOperationException(\"Day transform is not supported\");\n  }\n\n  default T hour(int fieldId, String sourceName, int sourceId) {\n    return hour(sourceName, sourceId);\n  }\n\n  default T hour(String sourceName, int sourceId) {\n    throw new UnsupportedOperationException(\"Hour transform is not supported\");\n  }\n\n  default T alwaysNull(int fieldId, String sourceName, int sourceId) {\n    throw new UnsupportedOperationException(\"Void transform is not supported\");\n  }\n\n  default T unknown(int fieldId, String sourceName, int sourceId, String transform) {\n    throw new UnsupportedOperationException(\n        String.format(\"Unknown transform %s is not supported\", transform));\n  }\n\n  /**\n   * Visit the fields of a {@link PartitionSpec}.\n   *\n   * @param spec a partition spec to visit\n   * @param visitor a partition spec visitor\n   * @param <R> return type of the visitor\n   * @return a list of the result produced by visiting each partition field\n   */\n  static <R> List<R> visit(PartitionSpec spec, PartitionSpecVisitor<R> visitor) {\n    List<R> results = Lists.newArrayListWithExpectedSize(spec.fields().size());\n\n    for (PartitionField field : spec.fields()) {\n      results.add(visit(spec.schema(), field, visitor));\n    }\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/transforms/PartitionSpecVisitor.java#L71-L107","documentation":"PartitionSpecVisitor's default unknown() throws UnsupportedOperationException when the spec contains an UnknownTransform — a transform that was written by a newer Iceberg version (or a custom Transform subclass) that the current visitor cannot interpret. visit() detects UnknownTransform and calls unknown(...) with the transform's string form so implementations can either map it or fail. The throwing default means the visitor has no policy for unrecognized transforms.","triggerScenarios":"PartitionSpecVisitor.visit on a table whose metadata references a transform not resolvable by the current version (e.g. table written by a newer Iceberg with a transform this build doesn't know), with a visitor lacking an unknown() override.","commonSituations":"Version skew: reading metadata produced by a newer Iceberg release or a vendor extension using custom transforms; rolling upgrades where an older engine reads a newer table's partition spec.","solutions":["Override unknown(int fieldId, String sourceName, int sourceId, String transform) to explicitly map or reject the unrecognized transform string","Upgrade the Iceberg version so the transform resolves to a known class instead of UnknownTransform","Identify the writer version from table metadata and either migrate the partition spec or use a compatible reader"],"exampleFix":"// before\ndefault unknown() -> UnsupportedOperationException\n// after\n@Override\npublic String unknown(int fieldId, String sourceName, int sourceId, String transform) {\n  throw new IllegalArgumentException(\"Spec uses unsupported transform \" + transform\n      + \"; upgrade Iceberg to read this table\");\n}","handlingStrategy":"validation","validationCode":"boolean hasUnknownTransform(PartitionSpec spec) {\n  return spec.fields().stream().anyMatch(f -> f.transform() instanceof UnknownTransform);\n}\n// true means the table was written by a newer/extended Iceberg — upgrade or handle explicitly","typeGuard":"if (field.transform() instanceof UnknownTransform) {\n  String name = field.transform().toString(); // decide policy per transform name\n}","tryCatchPattern":"try {\n  PartitionSpecVisitor.visit(spec, visitor);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().startsWith(\"Unknown transform\")) {\n    throw new IllegalStateException(\"Table written by newer Iceberg; upgrade to read spec\", e);\n  }\n  throw e;\n}","preventionTips":["Keep Iceberg versions aligned between writers and readers; unknown transforms signal version skew","Override unknown() to log and fail with the transform name for diagnosability","Check table metadata (writer version / format hints) before translating unknown specs"],"tags":["java","partitioning","version-skew","unknown-transform"],"backgroundTag":"unsupported-enum-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}