{"record":{"id":"5207a2d5418c0a57","repo":"apache/seatunnel","slug":"shard-cursor-error","errorCode":null,"errorMessage":"shard cursor error","messagePattern":"shard cursor error","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-sls/src/main/java/org/apache/seatunnel/connectors/seatunnel/sls/source/SlsSourceSplitEnumerator.java","lineNumber":195,"sourceCode":"                .forEach(\n                        shard -> {\n                            if (!assignedSplit.containsKey(shard.getShardId())) {\n                                if (!pendingSplit.containsKey(shard.getShardId())) {\n                                    String cursor = \"\";\n                                    try {\n                                        cursor =\n                                                initShardCursor(\n                                                        project,\n                                                        logStore,\n                                                        consumer,\n                                                        shard.getShardId(),\n                                                        startMode,\n                                                        autoCursorReset);\n                                    } catch (Exception e) {\n                                        throw new RuntimeException(e);\n                                    }\n                                    if (cursor.equals(\"\")) {\n                                        throw new RuntimeException(\"shard cursor error\");\n                                    }\n                                    SlsSourceSplit split =\n                                            new SlsSourceSplit(\n                                                    project,\n                                                    logStore,\n                                                    consumer,\n                                                    shard.getShardId(),\n                                                    cursor,\n                                                    fetachSize);\n                                    pendingSplit.put(shard.getShardId(), split);\n                                }\n                            }\n                        });\n    }\n\n    private String initShardCursor(\n            String project,\n            String logStore,","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-sls/src/main/java/org/apache/seatunnel/connectors/seatunnel/sls/source/SlsSourceSplitEnumerator.java#L177-L213","documentation":"The SLS (Aliyun Log Service) source split enumerator builds a shard read cursor during split assignment and throws this if the resolved cursor string is empty. An empty cursor means the consumer position could not be resolved from the log service, so the split would read nothing or behave unpredictably.","triggerScenarios":"fetchPendingShardSplit (called from discoverySplits) constructs a cursor via initShardCursor; if GetCursor succeeds through all cursor modes but the returned cursor string equals \"\", the RuntimeException is thrown.","commonSituations":"Empty logStore shards with no readable data for the requested cursor mode; misconfigured autoCursorReset values; logstore recently created/truncated so no cursor exists for the given mode.","solutions":["Check that the logStore and shard contain data for the configured cursor mode (e.g. begin/end/timestamp).","Verify cursorMode and autoCursorReset options are valid values supported by the SLS SDK.","Ensure the SLS credentials (project, accessKey) allow GetCursor on the logstore.","Add logging around initShardCursor to see which mode returned the empty cursor and retry with an explicit valid cursor mode."],"exampleFix":"// before\nif (cursor.equals(\"\")) {\n    throw new RuntimeException(\"shard cursor error\");\n}\n// after\nif (cursor == null || cursor.isEmpty()) {\n    throw new IllegalStateException(\n        \"SLS returned an empty cursor for shard \" + shardIdKey\n        + \" in logStore \" + logStore + \" with cursorMode \" + cursorMode\n        + \"; verify the shard has readable data or set autoCursorReset appropriately\");\n}","handlingStrategy":"validation","validationCode":"String cursor = initShardCursor(...); if (cursor == null || cursor.isEmpty()) { throw new IllegalStateException(\"empty SLS cursor for \" + logStore + \"/shard \" + shardIdKey + \", cursorMode=\" + cursorMode); }","typeGuard":null,"tryCatchPattern":"try { enumerator.discoverySplits(); } catch (RuntimeException e) { if (String.valueOf(e.getMessage()).contains(\"shard cursor error\")) { log.error(\"SLS shard cursor empty; check cursorMode/data\", e); throw new ConfigurationException(...); } throw e; }","preventionTips":["Verify the logStore has shards with readable data for the chosen cursor mode","Test GetCursor manually against the SLS endpoint before running the pipeline","Pin explicit cursorMode/autoCursorReset values in config rather than relying on fallbacks"],"tags":["sls","cursor","source-split"],"backgroundTag":"empty-required-field","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}