{"record":{"id":"94a764a07996c8d4","repo":"apache/iceberg","slug":"reading-partition-spec-from-manifest-file-metadata","errorCode":null,"errorMessage":"Reading partition spec from manifest file metadata is deprecated and will be removed in the 2.0.0 release. Pass specsById to avoid reading from file metadata: {}","messagePattern":"Reading partition spec from manifest file metadata is deprecated and will be removed in the 2\\.0\\.0 release\\. Pass specsById to avoid reading from file metadata: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/apache/iceberg/ManifestReader.java","lineNumber":159,"sourceCode":"      int specId,\n      Map<Integer, PartitionSpec> specsById,\n      InheritableMetadata inheritableMetadata,\n      Long firstRowId,\n      boolean isCommitted,\n      FileType content) {\n    Preconditions.checkArgument(\n        firstRowId == null || content == FileType.DATA_FILES,\n        \"First row ID is not valid for delete manifests\");\n    this.file = file;\n    this.inheritableMetadata = inheritableMetadata;\n    this.firstRowId = firstRowId;\n    this.isCommitted = isCommitted;\n    this.content = content;\n\n    if (specsById != null) {\n      this.spec = specsById.get(specId);\n    } else {\n      LOG.warn(\n          \"Reading partition spec from manifest file metadata is deprecated and will be \"\n              + \"removed in the 2.0.0 release. Pass specsById to avoid reading from file metadata: {}\",\n          file.location());\n      this.spec = readPartitionSpec(file);\n    }\n\n    this.fileSchema = new Schema(DataFile.getType(spec.rawPartitionType()).fields());\n  }\n\n  private <T extends ContentFile<T>> PartitionSpec readPartitionSpec(InputFile inputFile) {\n    Map<String, String> metadata = readMetadata(inputFile);\n\n    int specId = TableMetadata.INITIAL_SPEC_ID;\n    String specProperty = metadata.get(\"partition-spec-id\");\n    if (specProperty != null) {\n      specId = Integer.parseInt(specProperty);\n    }\n","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/ManifestReader.java#L141-L177","documentation":"Constructing a ManifestReader without a specsById map forces the reader to read and parse the partition spec from the manifest file's own metadata. This is deprecated (scheduled for removal in 2.0.0) because reading specs from file metadata is slow and unnecessary when the table metadata's spec map is available; the WARN prints the manifest location.","triggerScenarios":"Calling ManifestFiles.read(manifest) / new ManifestReader(...) without passing specsById, instead of the specsById-aware open(manifest, io, specsById) variants — commonly in custom scan/cleanup code or older integration paths.","commonSituations":"Custom maintenance or inspection code written against the old ManifestFiles API; third-party integrations not yet updated for the specsById parameter; copy-pasted example code from pre-1.x Iceberg.","solutions":["Pass the table's spec map: use ManifestFiles.open(manifest, fileIO, specsById) (or read(manifest, fileIO, specsById)) obtained from table.operations().current().specsById().","If only a ManifestFile is available, resolve specsById from the current TableMetadata instead of letting the reader parse the file.","Update dependent frameworks/connectors to an Iceberg version whose internal readers pass specsById.","Prepare for 2.0.0 where reading from file metadata is removed — the call will no longer work."],"exampleFix":"// before\nManifestReader<DataFile> reader = ManifestFiles.read(manifest, fileIO);\n// after\nMap<Integer, PartitionSpec> specsById = table.operations().current().specsById();\nManifestReader<DataFile> reader = ManifestFiles.read(manifest, fileIO, specsById);","handlingStrategy":"type-guard","validationCode":"if (manifest.hasCachedSpec() == false && specsById == null) {\n  throw new IllegalArgumentException(\"specsById is required to read manifests without cached specs\");\n}","typeGuard":"static boolean canReadWithoutSpecs(ManifestFile manifest) {\n  return manifest.hasCachedSpec(); // if false, always pass specsById\n}","tryCatchPattern":null,"preventionTips":["Always call ManifestFiles.read/open with the specsById overload when TableMetadata is available.","Fetch specsById via table.operations().current().specsById() in custom readers.","Update custom integrations before upgrading to 2.0.0 where file-metadata spec reading is removed.","Keep internal reader code in sync with ManifestFiles API changes per release notes."],"tags":["deprecation","manifests","partition-spec","api-change"],"backgroundTag":"deprecated-api-usage","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}