apache/iceberg · error · UnsupportedOperationException
Position delete writer does not support row data
Error message
Position delete writer does not support row data
What it means
ORC's DeleteWriteBuilder for position deletes only writes the (path, pos) schema. Unlike Parquet, ORC position delete writers do not support storing the deleted row alongside the position, so if a row schema (rowSchema) was supplied the builder throws UnsupportedOperationException.
Solutions
- Do not call rowSchema() for ORC position delete writers; write position-only deletes
- Switch the table's format to Parquet if row-in-position-delete is required
- Remove the rowSchema configuration from the delete write path
Example fix
// before deleteWriteBuilder.rowSchema(table.schema()); // throws for ORC // after deleteWriteBuilder.spec(spec).partition(partition); // position-only delete, no rowSchema
Defensive patterns
Strategy: type-guard
Validate before calling
if (format == FileFormat.ORC && rowSchema != null) {
throw new IllegalArgumentException("rowSchema is not supported for ORC position deletes");
} Type guard
boolean orcRowDeleteSupported(FileFormat f) { return f != FileFormat.ORC; } Try / catch
try {
appender = deleteWriteBuilder.build();
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("does not support row data")) {
throw new IllegalStateException("Write position-only deletes for ORC (drop rowSchema)", e);
} throw e;
} Prevention
- Never call rowSchema() on ORC delete write builders
- Choose Parquet if row-in-position-delete is required
- Keep delete-writer construction format-conditional in generic pipelines
When it happens
Trigger: Calling DeleteWriteBuilder.rowSchema(...) (or an API that sets it) before building an ORC position delete writer — i.e. writing format-version 2 position deletes with row data on ORC files.
Common situations: Porting a Parquet delete-writer code path to ORC; generic write pipelines that set rowSchema for all formats; using the merge-on-read row-in-delete feature with an ORC table.
Related errors
- ORC does not support AAD prefix
- ORC does not support file encryption keys
- Batch reading is not supported in non-vectorized reader
- Can't create file
- Can't get Stripe's length from the file writer with path
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ad59d3e97b22d9ad.
Report an issue: GitHub.
Appendix: source
Thrown at orc/src/main/java/org/apache/iceberg/orc/ORC.java:649
FileFormat.ORC,
location,
spec,
partition,
keyMetadata,
sortOrder,
equalityFieldIds);
}
public <T> PositionDeleteWriter<T> buildPositionWriter() {
Preconditions.checkState(
equalityFieldIds == null, "Cannot create position delete file using delete field ids");
Preconditions.checkArgument(
spec != null, "Spec must not be null when creating position delete writer");
Preconditions.checkArgument(
spec.isUnpartitioned() || partition != null,
"Partition must not be null for partitioned writes");
if (rowSchema != null) {
throw new UnsupportedOperationException("Position delete writer does not support row data");
}
meta("delete-type", "position");
appenderBuilder.schema(DeleteSchemaUtil.pathPosSchema());
// the createWriterFunc is ignored, since only the path and position are written
appenderBuilder.createWriterFunc(
(schema, typeDescription) ->
GenericOrcWriters.positionDelete(
GenericOrcWriter.buildWriter(schema, typeDescription), Function.identity()));
appenderBuilder.createContextFunc(WriteBuilder.Context::deleteContext);
return new PositionDeleteWriter<>(
appenderBuilder.build(), FileFormat.ORC, location, spec, partition, keyMetadata);
}
}View on GitHub (pinned to 86d9c8fc54)