apache/iceberg · error · IllegalArgumentException
Unknown file content:
Error message
Unknown file content:
What it means
AvroFormatModel's ModelWriteBuilder.build() switches on the configured FileContent (DATA, POSITION_DELETES, EQUALITY_DELETES). If the content was set to an unrecognized value, build throws IllegalArgumentException('Unknown file content: ' + content). This is an internal invariant guard over the builder's content field.
Solutions
- Only set FileContent values supported by the Avro writer: DATA, POSITION_DELETES, or the supported delete types
- Use the format-appropriate constant from FileContent instead of raw values
- Check that the generic write path does not forward content types unsupported by Avro
- Upgrade Iceberg if a newer content type must be written with Avro
Example fix
// before builder.withContent((FileContent) null); // leads to 'Unknown file content: null' // after builder.withContent(FileContent.DATA); // or FileContent.POSITION_DELETES
Defensive patterns
Strategy: validation
Validate before calling
if (content != FileContent.DATA && content != FileContent.POSITION_DELETES) { throw new IllegalArgumentException("Content not supported by Avro writer: " + content); } Type guard
boolean avroSupported(FileContent c) { return c == FileContent.DATA || c == FileContent.POSITION_DELETES; } Try / catch
try { return builder.build(); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unknown file content")) { /* correct the content or switch format */ } throw e; } Prevention
- Only pass FileContent enum constants supported by the Avro path
- Keep generic write code aligned with per-format capability
- Upgrade Iceberg when new FileContent types must be written
When it happens
Trigger: Setting a FileContent value on the Avro write builder that the switch does not handle — typically by passing a custom/incorrect enum value via withContent(), or a newly added FileContent type not yet supported by the Avro writer path.
Common situations: Generic write code passing content types supported only by other formats; version skew where a new Iceberg FileContent (e.g. equality deletes or future types) reaches an older Avro writer; misuse of the internal builder API with null or bogus content.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Avro does not support AAD prefix
- Avro does not support file encryption keys
- Avro does not support LOCAL TIMESTAMP type with precision
- Avro does not support LOCAL TIMESTAMP type with precision
- Avro does not support LOCAL TIMESTAMP type with precision
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/734a19d6ee16db7d.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/avro/AvroFormatModel.java:187
internal.createWriterFunc(
avroSchema -> writerFunction.write(schema, avroSchema, engineSchema));
break;
case POSITION_DELETES:
Preconditions.checkState(
schema == null,
"Invalid schema: %s. Position deletes with schema are not supported by the API.",
schema);
Preconditions.checkState(
engineSchema == null,
"Invalid engineSchema: %s. Position deletes with schema are not supported by the API.",
engineSchema);
internal.createContextFunc(Avro.WriteBuilder.Context::deleteContext);
internal.createWriterFunc(unused -> new Avro.PositionDatumWriter());
internal.schema(DeleteSchemaUtil.pathPosSchema());
break;
default:
throw new IllegalArgumentException("Unknown file content: " + content);
}
return internal.build();
}
}
private static class ReadBuilderWrapper<D, S> implements ReadBuilder<D, S> {
private final Avro.ReadBuilder internal;
private final ReaderFunction<DatumReader<D>, S, Schema> readerFunction;
private S engineSchema;
private Map<Integer, ?> idToConstant = ImmutableMap.of();
private ReadBuilderWrapper(
InputFile inputFile, ReaderFunction<DatumReader<D>, S, Schema> readerFunction) {
this.internal = Avro.read(inputFile);
this.readerFunction = readerFunction;
}
View on GitHub (pinned to 86d9c8fc54)