apache/iceberg · error · org.apache.iceberg.exceptions.ValidationException

Illegal file type: %s

Error message

Illegal file type: %s

What it means

The file-count accumulator in BaseSparkAction's compute/delete logic only recognizes DATA, DELETES, and OTHERS content type strings; anything else fails ValidationException. It is an internal invariant that manifest/file classification stays in sync with the known content kinds.

Source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/actions/BaseSparkAction.java:331

        positionDeleteFilesCount.addAndGet(numFiles);

      } else if (FileContent.EQUALITY_DELETES.name().equalsIgnoreCase(type)) {
        equalityDeleteFilesCount.addAndGet(numFiles);

      } else if (MANIFEST.equalsIgnoreCase(type)) {
        manifestsCount.addAndGet(numFiles);

      } else if (MANIFEST_LIST.equalsIgnoreCase(type)) {
        manifestListsCount.addAndGet(numFiles);

      } else if (STATISTICS_FILES.equalsIgnoreCase(type)) {
        statisticsFilesCount.addAndGet(numFiles);

      } else if (OTHERS.equalsIgnoreCase(type)) {
        otherFilesCount.addAndGet(numFiles);

      } else {
        throw new ValidationException("Illegal file type: %s", type);
      }
    }

    public void deletedFile(String path, String type) {
      if (FileContent.DATA.name().equalsIgnoreCase(type)) {
        dataFilesCount.incrementAndGet();
        LOG.trace("Deleted data file: {}", path);

      } else if (FileContent.POSITION_DELETES.name().equalsIgnoreCase(type)) {
        positionDeleteFilesCount.incrementAndGet();
        LOG.trace("Deleted positional delete file: {}", path);

      } else if (FileContent.EQUALITY_DELETES.name().equalsIgnoreCase(type)) {
        equalityDeleteFilesCount.incrementAndGet();
        LOG.trace("Deleted equality delete file: {}", path);

      } else if (MANIFEST.equalsIgnoreCase(type)) {
        manifestsCount.incrementAndGet();

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade the Iceberg Spark runtime so the action recognizes the new file type
  2. Check for version skew between the catalog/writer and the Spark action jars
  3. If due to custom code, ensure FileInfo/content strings are one of DATA, DELETES, OTHERS

Example fix

// before
} else if (OTHERS.equalsIgnoreCase(type)) { otherFilesCount.addAndGet(numFiles);
} else { throw new ValidationException("Illegal file type: %s", type); }
// after
// upgrade runtime, or extend the else-if chain to cover the new type before throwing
Defensive patterns

Strategy: validation

Try / catch

try { SparkActions.get(spark).rewriteDataFiles(table).execute(); }
catch (ValidationException e) {
  if (e.getMessage().startsWith("Illegal file type")) { /* upgrade Iceberg runtime */ }
  else throw e;
}

Prevention

When it happens

Trigger: Running Spark actions (e.g. expireSnapshots, deleteOrphanFiles, rewriteDataFiles) when a processed file reports a content string outside the three recognized buckets — typically new metadata file kinds added in newer specs.

Common situations: Newer Iceberg writers producing metadata/content file types read by an older Spark action runtime; plugin or custom FileIO reporting nonstandard type strings.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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