{"record":{"id":"34b479749f43a434","repo":"apache/iceberg","slug":"entries-must-have-explicit-snapshot-ids-if-inherit","errorCode":null,"errorMessage":"Entries must have explicit snapshot ids if inherited metadata is empty","messagePattern":"Entries must have explicit snapshot ids if inherited metadata is empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/InheritableMetadataFactory.java","lineNumber":116,"sourceCode":"    private CopyMetadata(long snapshotId) {\n      this.snapshotId = snapshotId;\n    }\n\n    @Override\n    public <F extends ContentFile<F>> ManifestEntry<F> apply(ManifestEntry<F> manifestEntry) {\n      manifestEntry.setSnapshotId(snapshotId);\n      return manifestEntry;\n    }\n  }\n\n  static class EmptyInheritableMetadata implements InheritableMetadata {\n\n    private EmptyInheritableMetadata() {}\n\n    @Override\n    public <F extends ContentFile<F>> ManifestEntry<F> apply(ManifestEntry<F> manifestEntry) {\n      if (manifestEntry.snapshotId() == null) {\n        throw new IllegalArgumentException(\n            \"Entries must have explicit snapshot ids if inherited metadata is empty\");\n      }\n      return manifestEntry;\n    }\n  }\n}\n","sourceCodeStart":98,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/InheritableMetadataFactory.java#L98-L123","documentation":"InheritableMetadataFactory.EmptyInheritableMetadata.apply() performs no inheritance, so a manifest entry without its own explicit snapshotId cannot be attributed to any snapshot and is rejected. This is a defensive check ensuring entries are never processed with unknown snapshot provenance.","triggerScenarios":"Reading manifest entries via a reader configured to not inherit metadata (e.g., ManifestReader without inheritable metadata set, or using EmptyInheritableMetadata) when an entry's snapshot-id field is null in the manifest file.","commonSituations":"Corrupt or hand-crafted manifest files missing snapshot-id; v1-era manifests read with inheritance disabled; custom code constructing ManifestEntry without snapshotId and applying it directly.","solutions":["Set the snapshot id explicitly on the manifest entry before applying inheritable metadata","Read manifests with a ManifestReader that inherits metadata from the manifest list (default) rather than empty metadata","Repair/rewrite corrupt manifest files missing snapshot-id fields","Use try-with-resources ManifestReader.read(manifest) with the manifest's own snapshot id passed in"],"exampleFix":"// before\nManifestEntry<DataFile> entry = new ManifestEntry<>(...);\nentry.setSnapshotId(null);\nemptyMetadata.apply(entry); // throws\n// after\nentry.setSnapshotId(manifest.snapshotId());\nemptyMetadata.apply(entry);","handlingStrategy":"validation","validationCode":"if (entry.snapshotId() == null) {\n  entry.setSnapshotId(manifestSnapshotId); // inherit before applying\n}","typeGuard":null,"tryCatchPattern":"try {\n  factory.apply(entry);\n} catch (IllegalArgumentException e) {\n  LOG.error(\"Manifest entry missing snapshot id: {}\", entry.file().location(), e);\n}","preventionTips":["Use default ManifestReader readers that inherit metadata","Never construct manifest entries with null snapshot ids for direct application","Validate manifest file integrity when ingesting externally produced manifests"],"tags":["java","manifest","metadata"],"backgroundTag":"missing-required-argument","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"}