apache/iceberg · error · IllegalArgumentException
Unsupported isolation level:
Error message
Unsupported isolation level:
What it means
SparkWrite.commit throws this IllegalArgumentException when the write is configured with an isolation level that the commit path does not recognize. Valid levels are none, serializable, and snapshot; anything else falls into the default branch of the switch on isolationLevel.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkWrite.java:489
for (DataFile file : files(messages)) {
numAddedFiles += 1;
overwriteFiles.addFile(file);
}
// the scan may be null if the optimizer replaces it with an empty relation (e.g. false cond)
// no validation is needed in this case as the command does not depend on the table state
if (scan != null) {
switch (isolationLevel) {
case SERIALIZABLE:
commitWithSerializableIsolation(
overwriteFiles, numOverwrittenFiles, numAddedFiles, summary);
break;
case SNAPSHOT:
commitWithSnapshotIsolation(
overwriteFiles, numOverwrittenFiles, numAddedFiles, summary);
break;
default:
throw new IllegalArgumentException("Unsupported isolation level: " + isolationLevel);
}
} else {
commitOperation(
overwriteFiles,
String.format(
Locale.ROOT, "overwrite with %d new data files (no validation)", numAddedFiles),
summary);
}
}
private void commitWithSerializableIsolation(
OverwriteFiles overwriteFiles,
int numOverwrittenFiles,
int numAddedFiles,
WriteSummary summary) {
Long scanSnapshotId = scan.snapshotId();
if (scanSnapshotId != null) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Set the isolation level to one of the supported values: none, serializable, or snapshot (e.g. write.format.option("isolation-level", "serializable"))
- Check for typos or case mismatches in the isolation-level option string
- If a new isolation level was added in code, update SparkWrite.commit to handle it explicitly
Example fix
// before
builder.option("isolation-level", "repeatable-read");
// after
builder.option("isolation-level", "serializable"); Defensive patterns
Strategy: validation
Validate before calling
// Java
String level = conf.get("isolation-level");
if (!Arrays.asList("none", "serializable", "snapshot").contains(level)) {
throw new IllegalArgumentException("isolation-level must be none|serializable|snapshot, got: " + level);
} Type guard
boolean isSupportedIsolationLevel(String level) {
return level != null && ("none".equals(level) || "serializable".equals(level) || "snapshot".equals(level));
} Try / catch
try {
write.commit();
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unsupported isolation level")) {
// rewrite options with a supported level and retry
}
throw e;
} Prevention
- Only pass none|serializable|snapshot as isolation-level
- After upgrading Iceberg, review any custom isolation-level handling
- Log effective write options before commit
When it happens
Trigger: Committing an overwrite/delete write whose IsolationLevel is neither Serializable nor Snapshot, i.e. a value outside the enum handled by the switch in SparkWrite.commit.
Common situations: Passing a custom or misparsed isolation level string via write options, code changes introducing a new IsolationLevel without updating SparkWrite, or deserializing stale state that carries an unknown level.
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
- Unsupported isolation level: " + isolationLevel
- Cannot parse order: parser is not an Iceberg ExtendedParser
- Cannot use catalog %s(%s): not a TableCatalog
- Invalid session catalog: sparkSessionCatalog
- Unsupported isolation level: ${isolationLevel}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/7be894b5b813529d.
Report an issue: GitHub.