apache/iceberg · error · ValidationException
Illegal file type: %s
Error message
Illegal file type: %s
What it means
BaseSparkAction's file-counting collector validates the content type string of each deleted/added file group. If the type is neither DATA, POSITION_DELETES, EQUALITY_DELETES, nor a recognized metadata/manifest/statistics type, it throws ValidationException 'Illegal file type: %s', signaling unrecognized content in a file group.
Source
Thrown at spark/v4.0/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 iceberg-spark to at least the version that wrote the table
- Inspect the file type string in the message and map it to the newest Iceberg spec
- Do not hand-edit table metadata; restore from a valid metadata snapshot if corrupted
Example fix
// before
} else {
throw new ValidationException("Illegal file type: %s", type);
}
// after
} else if (POSITION_DELETES.equalsIgnoreCase(type)) {
positionDeletesCount.addAndGet(numFiles);
} else {
throw new ValidationException("Illegal file type: %s", type);
} Defensive patterns
Strategy: validation
Validate before calling
Set<String> known = Set.of("DATA","POSITION_DELETES","EQUALITY_DELETES","MANIFEST","MANIFEST_LIST","INDEX","STATISTICS","OTHERS");
// before running actions, check no unknown content kinds appear in table files Try / catch
try { action.execute(); } catch (ValidationException e) { if (e.getMessage().startsWith("Illegal file type")) { LOG.error("Table written by newer Iceberg? Upgrade the runtime.", e); throw e; } throw e; } Prevention
- Keep iceberg-spark at or above the version that wrote the table
- Never hand-edit metadata files
- Coordinate Iceberg version rollouts across jobs
When it happens
Trigger: Running Spark actions (e.g. expireSnapshots, removeOrphanFiles, deleteFileGroup path) against table metadata containing a ContentFile/manifest content type string this Iceberg version does not know — usually tables written by a newer Iceberg version.
Common situations: Version skew: a newer Iceberg writes a new file content kind, then an older iceberg-spark processes the table; corrupted or hand-edited metadata.
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
- Illegal file type: %s
- Unable to determine whether certain files are orphan. Metada
- Cannot remove orphan files with an interval less than 24 hou
- Unsupported manifest content type:${content}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/d0c7aa14d61bb13a.
Report an issue: GitHub.