apache/iceberg · error · UnsupportedOperationException
Cannot read manifest with a deletion vector:
Error message
Cannot read manifest with a deletion vector:
What it means
Preconditions guard in V4ManifestReader's Builder: the manifest file being opened contains deletion vectors (a v4 feature) that this reader cannot process. The table location argument was already validated; the failure is purely about manifest content — a format-version/feature mismatch between the writer and this reader.
Solutions
- Upgrade Iceberg to a version that supports reading deletion vectors
- Write the table without deletion vectors (avoid v4 DV features)
- Fail fast with a clear message when detecting format-version-4 manifests with DVs
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at core/src/main/java/org/apache/iceberg/V4ManifestReader.java:221 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/48ca97d8e1b14214.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/V4ManifestReader.java:221
ManifestFile manifest,
FileIO io,
Map<Integer, PartitionSpec> specsById,
String tableLocation) {
Preconditions.checkArgument(tableLocation != null, "Invalid table location: null");
int formatVersion = manifest.formatVersion();
Preconditions.checkArgument(
formatVersion == SUPPORTED_FORMAT_VERSION,
"Cannot read manifest with format version %s: only %s is supported",
formatVersion,
SUPPORTED_FORMAT_VERSION);
Preconditions.checkState(
manifest.content() == ManifestContent.DATA,
"Cannot read manifest with content %s: only data manifests are supported: %s",
manifest.content(),
manifest.path());
if (manifest.manifestDeletionVector() != null) {
throw new UnsupportedOperationException(
"Cannot read manifest with a deletion vector: " + manifest.path());
}
this.manifest = manifest;
this.io = io;
this.specsById = specsById;
this.tableLocation = tableLocation;
this.unionPartitionType = Partitioning.unionPartitionTypes(specsById.values());
Schema base = TrackedFile.schema(unionPartitionType, Types.StructType.of());
// the read schema carries row_position (via BASE_TYPE) so the reader can fill manifestPos
this.fullSchema =
TypeUtil.replaceFieldTypes(
base, ImmutableMap.of(TrackedFile.TRACKING.fieldId(), TrackingStruct.BASE_TYPE));
}
/** Sets a filter; files that cannot match the expression are skipped. */
Builder filter(Expression expr) {
Preconditions.checkArgument(expr != null, "Invalid filter: null");View on GitHub (pinned to 86d9c8fc54)