apache/iceberg · warning

Reading partition spec from manifest file metadata is…

Error message

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: {}

What it means

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.

Solutions

  1. Pass the table's spec map: use ManifestFiles.open(manifest, fileIO, specsById) (or read(manifest, fileIO, specsById)) obtained from table.operations().current().specsById().
  2. If only a ManifestFile is available, resolve specsById from the current TableMetadata instead of letting the reader parse the file.
  3. Update dependent frameworks/connectors to an Iceberg version whose internal readers pass specsById.
  4. Prepare for 2.0.0 where reading from file metadata is removed — the call will no longer work.

Example fix

// before
ManifestReader<DataFile> reader = ManifestFiles.read(manifest, fileIO);
// after
Map<Integer, PartitionSpec> specsById = table.operations().current().specsById();
ManifestReader<DataFile> reader = ManifestFiles.read(manifest, fileIO, specsById);
Defensive patterns

Strategy: type-guard

Validate before calling

if (manifest.hasCachedSpec() == false && specsById == null) {
  throw new IllegalArgumentException("specsById is required to read manifests without cached specs");
}

Type guard

static boolean canReadWithoutSpecs(ManifestFile manifest) {
  return manifest.hasCachedSpec(); // if false, always pass specsById
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/94a764a07996c8d4. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/ManifestReader.java:159

      int specId,
      Map<Integer, PartitionSpec> specsById,
      InheritableMetadata inheritableMetadata,
      Long firstRowId,
      boolean isCommitted,
      FileType content) {
    Preconditions.checkArgument(
        firstRowId == null || content == FileType.DATA_FILES,
        "First row ID is not valid for delete manifests");
    this.file = file;
    this.inheritableMetadata = inheritableMetadata;
    this.firstRowId = firstRowId;
    this.isCommitted = isCommitted;
    this.content = content;

    if (specsById != null) {
      this.spec = specsById.get(specId);
    } else {
      LOG.warn(
          "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: {}",
          file.location());
      this.spec = readPartitionSpec(file);
    }

    this.fileSchema = new Schema(DataFile.getType(spec.rawPartitionType()).fields());
  }

  private <T extends ContentFile<T>> PartitionSpec readPartitionSpec(InputFile inputFile) {
    Map<String, String> metadata = readMetadata(inputFile);

    int specId = TableMetadata.INITIAL_SPEC_ID;
    String specProperty = metadata.get("partition-spec-id");
    if (specProperty != null) {
      specId = Integer.parseInt(specProperty);
    }

View on GitHub (pinned to 86d9c8fc54)