{"record":{"id":"df82f837c6e85b13","repo":"apache/seatunnel","slug":"unsupported-operation-df82f8","errorCode":"UNSUPPORTED_OPERATION","errorMessage":"Unsupported stream scan strategy: ","messagePattern":"Unsupported stream scan strategy: ","errorType":"error_code","errorClass":"IcebergConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/source/enumerator/scan/IcebergScanSplitPlanner.java","lineNumber":164,"sourceCode":"            case FROM_LATEST_SNAPSHOT:\n                return Optional.ofNullable(table.currentSnapshot());\n            case FROM_EARLIEST_SNAPSHOT:\n                return Optional.ofNullable(SnapshotUtil.oldestAncestor(table));\n            case FROM_SNAPSHOT_ID:\n                return Optional.of(table.snapshot(icebergScanContext.getStartSnapshotId()));\n            case FROM_SNAPSHOT_TIMESTAMP:\n                long snapshotIdAsOfTime =\n                        SnapshotUtil.snapshotIdAsOfTime(\n                                table, icebergScanContext.getStartSnapshotTimestamp());\n                Snapshot matchedSnapshot = table.snapshot(snapshotIdAsOfTime);\n                if (matchedSnapshot.timestampMillis()\n                        == icebergScanContext.getStartSnapshotTimestamp()) {\n                    return Optional.of(matchedSnapshot);\n                } else {\n                    return Optional.of(SnapshotUtil.snapshotAfter(table, snapshotIdAsOfTime));\n                }\n            default:\n                throw new IcebergConnectorException(\n                        CommonErrorCodeDeprecated.UNSUPPORTED_OPERATION,\n                        \"Unsupported stream scan strategy: \"\n                                + icebergScanContext.getStreamScanStrategy());\n        }\n    }\n\n    public static List<IcebergFileScanTaskSplit> planSplits(\n            Table table, IcebergScanContext context) {\n        try (CloseableIterable<CombinedScanTask> tasksIterable = planTasks(table, context)) {\n            List<IcebergFileScanTaskSplit> splits = new ArrayList<>();\n            for (CombinedScanTask combinedScanTask : tasksIterable) {\n                for (FileScanTask fileScanTask : combinedScanTask.files()) {\n                    splits.add(new IcebergFileScanTaskSplit(context.getTablePath(), fileScanTask));\n                }\n            }\n            return splits;\n        } catch (IOException e) {\n            throw new IcebergConnectorException(","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/source/enumerator/scan/IcebergScanSplitPlanner.java#L146-L182","documentation":"IcebergScanSplitPlanner.getStreamStartSnapshot() resolves the starting snapshot for streaming reads from the configured StreamScanStrategy enum; any strategy value it doesn't recognize hits the default branch and throws IcebergConnectorException(UNSUPPORTED_OPERATION). This guards against unknown or future strategy values.","triggerScenarios":"Streaming mode with a stream.scan-strategy config value not covered by the switch (typo, or a strategy added in a newer Iceberg connector version while running an older/patched build).","commonSituations":"Typos in stream-scan-strategy config; mixing connector/plugin jar versions so enum deserialization yields an unhandled constant.","solutions":["Check the configured stream scan strategy value; valid options are the connector's enum constants (e.g. from-latest-snapshot, from-earliest-snapshot, from-snapshot-id, from-snapshot-timestamp, from-snapshot-reference, incremental)","Fix the typos in job config and restart the job","Align the connector plugin version with the version that wrote the config (install-plugin with matching version)","If this occurs with a valid value, report a bug — the switch in getStreamStartSnapshot is missing a case"],"exampleFix":"// before\nstream-scan-strategy = \"form-latest-snapshot\"\n// after\nstream-scan-strategy = \"from-latest-snapshot\"","handlingStrategy":"validation","validationCode":"// Validate the strategy against the connector's enum before submitting the job\nSet<String> valid = Set.of(\"from-latest-snapshot\",\"from-earliest-snapshot\",\"from-snapshot-id\",\"from-snapshot-timestamp\",\"from-snapshot-reference\",\"incremental\");\nif (!valid.contains(cfg.get(\"stream-scan-strategy\"))) throw new IllegalArgumentException(\"invalid stream-scan-strategy\");","typeGuard":null,"tryCatchPattern":"try { planStream(); } catch (IcebergConnectorException e) { if (e.getSeaTunnelErrorCode() == UNSUPPORTED_OPERATION && e.getMessage().contains(\"Unsupported stream scan strategy\")) { /* fix config and resubmit */ } throw e; }","preventionTips":["Copy strategy values only from official connector docs","Pin connector plugin version matching your config examples","Validate job config with the CLI before deployment"],"tags":["iceberg","config","streaming"],"backgroundTag":"invalid-enum-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}