apache/iceberg · error · RuntimeException

Reader does not support metadata reading: %s

Error message

Reader does not support metadata reading: %s

What it means

ManifestReader.readMetadata expects the iterable produced by InternalData.read(...) to be an AvroIterable exposing file-level metadata; if the reader implementation is a different class it cannot supply metadata, so a plain RuntimeException is thrown naming the reader class. This guards an internal assumption that manifest files are Avro.

Source

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

    return PartitionSpecParser.fromJsonFields(schema, specId, metadata.get("partition-spec"));
  }

  private static <T extends ContentFile<T>> Map<String, String> readMetadata(InputFile inputFile) {
    FileFormat manifestFormat = FileFormat.fromFileName(inputFile.location());
    Preconditions.checkArgument(
        manifestFormat == FileFormat.AVRO,
        "Reading manifest metadata is only supported for Avro manifests: %s",
        inputFile.location());

    Map<String, String> metadata;
    try {
      try (CloseableIterable<ManifestEntry<T>> headerReader =
          InternalData.read(FileFormat.AVRO, inputFile).project(STATUS_ONLY_PROJECTION).build()) {

        if (headerReader instanceof AvroIterable) {
          metadata = ((AvroIterable<ManifestEntry<T>>) headerReader).getMetadata();
        } else {
          throw new RuntimeException(
              "Reader does not support metadata reading: " + headerReader.getClass().getName());
        }
      }
    } catch (IOException e) {
      throw new RuntimeIOException(e);
    }
    return metadata;
  }

  public boolean isDeleteManifestReader() {
    return content == FileType.DELETE_FILES;
  }

  public InputFile file() {
    return file;
  }

  public Schema schema() {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Ensure manifest files are read with the default InternalData.read(FileFormat.AVRO, ...) path.
  2. Check any custom InternalData/FileIO reader registration that changes the returned iterable class.
  3. Remove or fix test doubles that return non-AvroIterable implementations.
  4. Verify the file is actually an Iceberg Avro manifest and not a foreign or corrupted format.

Example fix

// before: stub returning plain iterable in tests
when(data.read(any(), any())).thenReturn(CloseableIterable.withNoopClose(List.of()));
// after: return an AvroIterable-compatible stub or use a real test manifest file
AvroIterable<ManifestEntry<DataFile>> it = Avro.read(file).project(STATUS_ONLY_PROJECTION).build();
when(data.read(any(), any())).thenReturn(it);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(iterable instanceof AvroIterable)) {
  throw new IllegalStateException("Expected AvroIterable from InternalData.read, got " + iterable.getClass());
}

Type guard

static boolean isAvroIterable(CloseableIterable<?> it) {
  return it instanceof AvroIterable;
}

Try / catch

try {
  Map<String, String> meta = ManifestFiles.read(manifest, io).metadata();
} catch (RuntimeException e) {
  if (e.getMessage().contains("does not support metadata reading")) {
    // fall back to re-reading with the default Avro path
  }
}

Prevention

When it happens

Trigger: Calling ManifestReader.metadata() (or read in a way that triggers readMetadata) on a file whose data reader is not an AvroIterable — e.g., a custom InternalData/FileIO reader plugged in, or a manifest file in an unexpected format.

Common situations: Custom FileIO/data implementations returning non-Avro readers; plugging experimental file formats into InternalData; unit-test stubs returning generic CloseableIterable instead of AvroIterable.

Related errors


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