apache/iceberg · error · UncheckedIOException

Failed to validate no appends matching %s

Error message

Failed to validate no appends matching %s

What it means

When the conflict validation scan for added data files throws an IOException (while iterating manifests during addedDataFiles), the ValidationException path can't run and the error is wrapped in this UncheckedIOException, naming the partition set that was being validated. It signals an I/O failure reading manifest files during commit-time validation, not a logical conflict.

Source

Thrown at core/src/main/java/org/apache/iceberg/MergingSnapshotProducer.java:378

   * @param partitionSet a set of partitions to filter new conflicting data files
   * @param parent ending snapshot on the lineage being validated
   */
  protected void validateAddedDataFiles(
      TableMetadata base, Long startingSnapshotId, PartitionSet partitionSet, Snapshot parent) {
    CloseableIterable<ManifestEntry<DataFile>> conflictEntries =
        addedDataFiles(base, startingSnapshotId, null, partitionSet, parent);

    try (CloseableIterator<ManifestEntry<DataFile>> conflicts = conflictEntries.iterator()) {
      if (conflicts.hasNext()) {
        throw new ValidationException(
            "Found conflicting files that can contain records matching partitions %s: %s",
            partitionSet,
            Iterators.toString(
                Iterators.transform(conflicts, entry -> entry.file().location().toString())));
      }

    } catch (IOException e) {
      throw new UncheckedIOException(
          String.format("Failed to validate no appends matching %s", partitionSet), e);
    }
  }

  /**
   * Validates that no files matching a filter have been added to the table since a starting
   * snapshot.
   *
   * @param base table metadata to validate
   * @param startingSnapshotId id of the snapshot current at the start of the operation
   * @param conflictDetectionFilter an expression used to find new conflicting data files
   */
  protected void validateAddedDataFiles(
      TableMetadata base,
      Long startingSnapshotId,
      Expression conflictDetectionFilter,
      Snapshot parent) {
    CloseableIterable<ManifestEntry<DataFile>> conflictEntries =

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Re-run the operation after refreshing the table (fresh metadata references intact manifests)
  2. Restore/avoid deleting manifests of snapshots still in use (raise history.expire.min-snapshots-kept-to-keep or pause expire during jobs)
  3. Verify storage credentials and network access to manifest files
  4. Check for orphaned or manually deleted manifest files in the metadata chain

Example fix

// before: long job validates against expired snapshots
// after: keep enough snapshots for in-flight jobs
table.updateProperties().set(TableProperties.MIN_SNAPSHOTS_TO_KEEP, "10").commit();
Defensive patterns

Strategy: retry

Try / catch

try { producer.commit(); } catch (UncheckedIOException e) { if (e.getMessage().startsWith("Failed to validate no appends")) { /* refresh table and retry with backoff */ } throw e; }

Prevention

When it happens

Trigger: Manifest files referenced by the snapshot are missing/unreadable during validateAddedDataFiles (deleted by concurrent expire/rewrite, object-store transient errors, or permission problems) while the producer checks for conflicting appends in the given partitions.

Common situations: Snapshot expiry removing manifests that a long-running job still validates against; S3 404/403 during manifest reads; HDFS outage mid-commit; orphan/externally deleted metadata.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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