{"record":{"id":"42e1ee32887b449c","repo":"apache/iceberg","slug":"failed-to-read-footer-of-file-s","errorCode":null,"errorMessage":"Failed to read footer of file: %s","messagePattern":"Failed to read footer of file: (.+?)","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/ParquetUtil.java","lineNumber":67,"sourceCode":"import org.apache.parquet.schema.MessageType;\nimport org.apache.parquet.schema.PrimitiveType;\n\npublic class ParquetUtil {\n  // not meant to be instantiated\n  private ParquetUtil() {}\n\n  private static final long UNIX_EPOCH_JULIAN = 2_440_588L;\n\n  public static Metrics fileMetrics(InputFile file, MetricsConfig metricsConfig) {\n    return fileMetrics(file, metricsConfig, null);\n  }\n\n  public static Metrics fileMetrics(\n      InputFile file, MetricsConfig metricsConfig, NameMapping nameMapping) {\n    try (ParquetFileReader reader = ParquetFileReader.open(ParquetIO.file(file))) {\n      return footerMetrics(reader.getFooter(), Stream.empty(), metricsConfig, nameMapping);\n    } catch (IOException e) {\n      throw new RuntimeIOException(e, \"Failed to read footer of file: %s\", file.location());\n    }\n  }\n\n  public static Metrics footerMetrics(\n      ParquetMetadata metadata, Stream<FieldMetrics<?>> fieldMetrics, MetricsConfig metricsConfig) {\n    return footerMetrics(metadata, fieldMetrics, metricsConfig, null);\n  }\n\n  public static Metrics footerMetrics(\n      ParquetMetadata metadata,\n      Stream<FieldMetrics<?>> fieldMetrics,\n      MetricsConfig metricsConfig,\n      NameMapping nameMapping) {\n    Preconditions.checkNotNull(fieldMetrics, \"fieldMetrics should not be null\");\n    MessageType parquetTypeWithIds = getParquetTypeWithIds(metadata, nameMapping);\n    Schema fileSchema = ParquetSchemaUtil.convertAndPrune(parquetTypeWithIds);\n    return ParquetMetrics.metrics(\n        fileSchema, parquetTypeWithIds, metricsConfig, metadata, fieldMetrics);","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/ParquetUtil.java#L49-L85","documentation":"ParquetUtil.fileMetrics opens the Parquet file to read its footer for computing column metrics (counts, min/max, null counts). If opening the reader or reading the footer throws IOException, it is wrapped as RuntimeIOException with the file location included. It indicates the file's metadata could not be read, so metrics collection failed.","triggerScenarios":"Calling ParquetUtil.fileMetrics(InputFile, MetricsConfig, NameMapping) where ParquetFileReader.open fails (file missing/unreadable) or reader.getFooter() fails (corrupt/truncated footer, not a Parquet file).","commonSituations":"Pointing metrics collection at a non-Parquet or truncated file; missing storage credentials; file deleted between planning and metrics computation; corrupt files from interrupted writes.","solutions":["Verify the file exists and is a complete, valid Parquet file at the given location.","Check the wrapped IOException cause; validate the file with a Parquet metadata tool.","Confirm storage credentials/configuration for the InputFile's filesystem.","If the file is corrupt, remove it from the table via Iceberg metadata operations and rewrite from a valid snapshot."],"exampleFix":"// before\nMetrics m = ParquetUtil.fileMetrics(files.newInputFile(location), metricsConfig, null);\n// after\nif (files.newInputFile(location).exists()) {\n  Metrics m = ParquetUtil.fileMetrics(files.newInputFile(location), metricsConfig, null);\n}","handlingStrategy":"validation","validationCode":"InputFile f = files.newInputFile(location);\nif (!f.exists()) {\n  throw new FileNotFoundException(\"Missing parquet file: \" + location);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return ParquetUtil.fileMetrics(file, metricsConfig, nameMapping);\n} catch (RuntimeIOException e) {\n  LOG.error(\"Cannot read footer of {}\", file.location(), e.getCause());\n  throw e;\n}","preventionTips":["Confirm the file exists and is a complete Parquet file before computing metrics.","Check credentials/config for the file's filesystem.","Exclude files from failed writes; read only committed snapshots."],"tags":["parquet","metrics","footer","file-read"],"backgroundTag":"file-read-failed","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"}