apache/iceberg · error · IllegalArgumentException
Unsupported isolation level: " + isolationLevel
Error message
Unsupported isolation level: " + isolationLevel
What it means
SparkWrite.commit throws IllegalArgumentException when the write's configured isolation level is neither SERIALIZABLE nor SNAPSHOT. Iceberg only supports these two isolation modes for Copy-On-Write overwrite/DELETE operations; any other value reaching the commit path is a programming or configuration bug.
Source
Thrown at spark/v4.1/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
- Ensure the write is configured with 'serializable' or 'snapshot' isolation level only
- Check the writer/builder code that constructs SparkWrite and the option it reads (write isolation level) for invalid values
- If supporting a new Spark isolation level, extend the switch to map it onto SNAPSHOT or SERIALIZABLE commit paths
- Upgrade Iceberg so the switch in SparkWrite.commit covers your Spark version's isolation levels
Example fix
// before
writeConf.isolationLevel() // returns e.g. READ_COMMITTED
// after
conf.set("spark.sql.sources.writeIsolationLevel", "serializable"); // or snapshot Defensive patterns
Strategy: validation
Validate before calling
String level = spark.conf().get("spark.sql.sources.writeIsolationLevel", "serializable");
if (!level.equalsIgnoreCase("serializable") && !level.equalsIgnoreCase("snapshot")) {
throw new IllegalArgumentException("isolationLevel must be 'serializable' or 'snapshot', got: " + level);
} Try / catch
try { write.commit(); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unsupported isolation level")) { /* reconfigure and retry */ } else throw e; } Prevention
- Only configure 'serializable' or 'snapshot' as Iceberg write isolation levels
- Keep the isolation-level option mapping in sync between Spark SQL config and Iceberg options
- Test custom writers against both supported enum values before deploying
When it happens
Trigger: Executing a dynamic-overwrite or DELETE (copy-on-write) SparkWrite whose isolationLevel field is not IsolationLevel.SERIALIZABLE or IsolationLevel.SNAPSHOT — typically set programmatically via SparkWriteOptions or a custom writer, or a non-exhaustive switch after adding a new Spark SQL isolation level.
Common situations: Custom Spark connectors or forks that set their own isolation level string/enum; Spark sessions or newer Spark versions introducing an isolation level Iceberg's switch does not handle; typos in write option mapping.
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
- Invalid session catalog:
- Unsupported isolation level:
- Cannot parse order: parser is not an Iceberg ExtendedParser
- Cannot use catalog %s(%s): not a TableCatalog
- Invalid session catalog: sparkSessionCatalog
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/98eda807e7766d57.
Report an issue: GitHub.