{"record":{"id":"c111fdedf5947971","repo":"apache/iceberg","slug":"cannot-process-unknown-snapshot-operation-op-to","errorCode":null,"errorMessage":"Cannot process unknown snapshot operation: ${op.toLowerCase(Locale.ROOT)} (snapshot id ${snapshot.snapshotId()})","messagePattern":"Cannot process unknown snapshot operation: (.+?) \\(snapshot id (.+?)\\)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/BaseSparkMicroBatchPlanner.java","lineNumber":76,"sourceCode":"        return true;\n      case DataOperations.REPLACE:\n        return false;\n      case DataOperations.DELETE:\n        Preconditions.checkState(\n            readConf.streamingSkipDeleteSnapshots(),\n            \"Cannot process delete snapshot: %s, to ignore deletes, set %s=true\",\n            snapshot.snapshotId(),\n            SparkReadOptions.STREAMING_SKIP_DELETE_SNAPSHOTS);\n        return false;\n      case DataOperations.OVERWRITE:\n        Preconditions.checkState(\n            readConf.streamingSkipOverwriteSnapshots(),\n            \"Cannot process overwrite snapshot: %s, to ignore overwrites, set %s=true\",\n            snapshot.snapshotId(),\n            SparkReadOptions.STREAMING_SKIP_OVERWRITE_SNAPSHOTS);\n        return false;\n      default:\n        throw new IllegalStateException(\n            String.format(\n                \"Cannot process unknown snapshot operation: %s (snapshot id %s)\",\n                op.toLowerCase(Locale.ROOT), snapshot.snapshotId()));\n    }\n  }\n\n  /**\n   * Get the next snapshot skipping over rewrite and delete snapshots. Async must handle nulls.\n   *\n   * @param curSnapshot the current snapshot\n   * @return the next valid snapshot (not a rewrite or delete snapshot), returns null if all\n   *     remaining snapshots should be skipped.\n   */\n  protected Snapshot nextValidSnapshot(Snapshot curSnapshot) {\n    Snapshot nextSnapshot;\n    // if there were no valid snapshots, check for an initialOffset again\n    if (curSnapshot == null) {\n      StreamingOffset startingOffset =","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/BaseSparkMicroBatchPlanner.java#L58-L94","documentation":"BaseSparkMicroBatchPlanner.shouldProcess switches on the snapshot operation to decide whether a snapshot advances the stream offset. The default branch throws IllegalStateException for operations not covered by the streaming-skip options, i.e. snapshot summaries with an unexpected or newly added operation value.","triggerScenarios":"A snapshot whose summary operation is not append/replace/overwrite/delete (e.g. a future or custom operation value) is encountered by nextValidSnapshot during streaming micro-batch planning.","commonSituations":"Reading a table written by a newer Iceberg version or non-Iceberg tooling that emits a new snapshot operation type; corrupted snapshot summaries.","solutions":["Inspect the offending snapshot's summary.operation to identify the unexpected value.","Upgrade Spark/Iceberg runtime to a version that understands the new operation type.","Exclude or archive the offending snapshot/table branch; re-point the stream to a snapshot before it (set streaming-from-snapshot-id).","If produced by external tooling, fix the writer so it emits valid Iceberg operations."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"Table table = sparkTable.loadedTable();\nfor (Snapshot snap : table.snapshots()) {\n  String op = snap.operation();\n  if (!\"append\".equals(op) && !\"replace\".equals(op)\n      && !\"overwrite\".equals(op) && !\"delete\".equals(op)) {\n    throw new IllegalStateException(\"Snapshot \" + snap.snapshotId() + \" has unsupported op: \" + op);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  streamingDf.writeStream().start();\n} catch (StreamingQueryException e) {\n  if (String.valueOf(e.getCause() != null ? e.getCause().getMessage() : null)\n      .startsWith(\"Cannot process unknown snapshot operation\")) {\n    // upgrade Iceberg or exclude the offending snapshot\n  } else { throw e; }\n}","preventionTips":["Keep reader and writer Iceberg versions in sync.","Only write tables with standard Iceberg tooling.","Set streaming skip options (e.g. streaming-skip-overwrite-snapshots) where appropriate so known ops are handled."],"tags":["spark","streaming","snapshot","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}