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
- Upgrade the Iceberg Spark runtime so the action recognizes the new file type
- Check for version skew between the catalog/writer and the Spark action jars
- 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
- Run actions with a runtime at least as new as the writer
- Keep catalog, writer, and action jars on the same Iceberg version
- Watch spec releases for new file kinds
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
- Illegal file type: %s
- Cannot find source table '%s'
- Cannot use non-v1 table '%s' as a source
- Unable to determine whether certain files are orphan. Metada
- Cannot remove orphan files with an interval less than 24 hou
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/35cf3a51204eafac.
Report an issue: GitHub.