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

  1. Use Append mode for streaming writes, or a valid overwrite mode handled by asStreamingOverwrite
  2. Restructure the job to avoid streaming delete/truncate modes (e.g. batch job for deletes)
  3. 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

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


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)