apache/iceberg · error · IllegalArgumentException

Invalid isolation level: %s

Error message

Invalid isolation level: %s

What it means

IsolationLevel.fromName parses a string into the IsolationLevel enum case-insensitively; a null input gets a dedicated message, and any name not matching SERIALIZABLE or SNAPSHOT rethrows IllegalArgumentException with the offending value and the underlying cause.

Source

Thrown at core/src/main/java/org/apache/iceberg/IsolationLevel.java:48

 * isolation is beneficial for environments with many concurrent writers.
 *
 * <p>The serializable isolation level guarantees that an ongoing UPDATE/DELETE/MERGE operation
 * fails if a concurrent transaction commits a new file that might contain rows matching the
 * condition used in UPDATE/DELETE/MERGE. For example, if there is an ongoing update on a subset of
 * rows and a concurrent transaction adds a new file with records that potentially match the update
 * condition, the update operation must fail under the serializable isolation but can still commit
 * under the snapshot isolation.
 */
public enum IsolationLevel {
  SERIALIZABLE,
  SNAPSHOT;

  public static IsolationLevel fromName(String levelName) {
    Preconditions.checkArgument(levelName != null, "Invalid isolation level: null");
    try {
      return IsolationLevel.valueOf(levelName.toUpperCase(Locale.ROOT));
    } catch (IllegalArgumentException e) {
      throw new IllegalArgumentException(
          String.format("Invalid isolation level: %s", levelName), e);
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Set the value to exactly 'serializable' or 'snapshot' (any case)
  2. Trim whitespace/newlines from the configured value
  3. Handle null by defaulting to SERIALIZABLE explicitly in calling code

Example fix

// before
conf.set("isolation-level", "read-committed");
// after
conf.set("isolation-level", "snapshot");
Defensive patterns

Strategy: validation

Validate before calling

String v = raw == null ? null : raw.trim();
boolean valid = "serializable".equalsIgnoreCase(v) || "snapshot".equalsIgnoreCase(v);
if (!valid) throw new IllegalArgumentException("Bad isolation level: " + raw);

Try / catch

try {
  IsolationLevel level = IsolationLevel.fromName(raw);
} catch (IllegalArgumentException e) {
  level = IsolationLevel.SERIALIZABLE; // documented default
}

Prevention

When it happens

Trigger: Passing an isolation-level string (e.g., table property or config value) that is neither 'serializable' nor 'snapshot' (case-insensitive), or null.

Common situations: Typo in table properties like write.wap / retry config; value like 'SERIALIZABLE ' with trailing whitespace; users supplying 'strict' or 'read-committed' which Iceberg does not support.

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/64b813ad56b6b645. Report an issue: GitHub.