apache/iceberg · error · IllegalStateException
Unsupported streaming write mode:
Error message
Unsupported streaming write mode:
What it means
SparkWriteBuilder.toStreaming throws this IllegalStateException when a streaming query requests a write mode that Iceberg's Spark streaming sink does not support. Only Append (or a null mode treated as append) and the Complete/Update overwrite paths are handled.
Solutions
- Use Append mode for streaming writes, or a valid overwrite mode handled by asStreamingOverwrite
- Restructure the job to avoid streaming delete/truncate modes (e.g. batch job for deletes)
- Upgrade Iceberg if a newer version supports the desired streaming mode
Example fix
// before writeToSink(sinkMode = STREAMING_DELETE); // after writeToSink(sinkMode = STREAMING_APPEND);
Defensive patterns
Strategy: validation
Validate before calling
// Java
if (!(mode instanceof Append) && !(mode instanceof Overwrite) && mode != null) {
throw new UnsupportedOperationException("Streaming write mode not supported: " + mode);
} Type guard
boolean isStreamingAppendMode(Object mode) {
return mode == null || mode instanceof Append;
} Try / catch
try {
sparkWrite = writeBuilder.toStreaming();
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Unsupported streaming write mode")) {
// fall back to batch write or reconfigure to append
}
throw e;
} Prevention
- Use append (or supported overwrite) modes for streaming sinks
- Do deletes/truncates in batch jobs, not streaming
- Check supported modes for your Iceberg version before configuring the stream
When it happens
Trigger: Invoking toStreaming with a mode such as StreamingDelete or any other SaveMode/WriteMode instance that is not Append and not handled by the branch above the throw.
Common situations: Using Iceberg as a streaming sink with an unsupported write mode (e.g. truncate or delete semantics in micro-batch), or framework upgrades passing new mode types the connector does not yet support.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot load current offset at snapshot
- Cannot load current offset at snapshot
- Cannot load current offset at snapshot
- Cannot process unknown snapshot operation
- Cannot process unknown snapshot operation
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/456939cfbcdff34f.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkWriteBuilder.java:170
return asDynamicOverwrite();
} else if (mode instanceof CopyOnWriteOperation cow) {
return asCopyOnWriteOperation(cow.scan(), cow.isolationLevel());
} else {
return asBatchAppend();
}
}
@Override
public StreamingWrite toStreaming() {
if (mode instanceof OverwriteByFilter overwrite) {
Preconditions.checkState(
overwrite.expr() == Expressions.alwaysTrue(),
"Unsupported streaming overwrite filter: " + overwrite.expr());
return asStreamingOverwrite();
} else if (mode == null || mode instanceof Append) {
return asStreamingAppend();
} else {
throw new IllegalStateException("Unsupported streaming write mode: " + mode);
}
}
};
}
private SparkWriteRequirements writeRequirements() {
if (mode instanceof CopyOnWriteOperation cow) {
return writeConf.copyOnWriteRequirements(cow.command());
} else {
return writeConf.writeRequirements();
}
}
private void validateRowLineage() {
Preconditions.checkArgument(
writeIncludesRowLineage() || !writeNeedsRowLineage(),
"Row lineage information is missing for write in mode: %s",
mode);View on GitHub (pinned to 86d9c8fc54)