{"record":{"id":"0d3f4dc8e9f8aef0","repo":"apache/seatunnel","slug":"reader-is-not-registered-pending-splits-are-0d3f4d","errorCode":null,"errorMessage":"Reader {} is not registered. Pending splits {} are not assigned.","messagePattern":"Reader (.+?) is not registered\\. Pending splits (.+?) are not assigned\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-iotdb-v2/src/main/java/org/apache/seatunnel/connectors/seatunnel/iotdbv2/source/IoTDBv2SourceSplitEnumerator.java","lineNumber":195,"sourceCode":"                query = query + \" and ( \" + sqlCondition + \" ) \";\n            }\n            if (!Strings.isNullOrEmpty(sqlAlign)) {\n                query = query + \" align by \" + sqlAlign;\n            }\n            iotDBSourceSplits.add(new IoTDBv2SourceSplit(String.valueOf(query.hashCode()), query));\n        }\n        return iotDBSourceSplits;\n    }\n\n    @Override\n    public void addSplitsBack(List<IoTDBv2SourceSplit> splits, int subtaskId) {\n        log.debug(\"Add back splits {} to IoTDBSourceSplitEnumerator.\", splits);\n        if (!splits.isEmpty()) {\n            addPendingSplit(splits, subtaskId);\n            if (context.registeredReaders().contains(subtaskId)) {\n                assignSplit(Collections.singletonList(subtaskId));\n            } else {\n                log.warn(\n                        \"Reader {} is not registered. Pending splits {} are not assigned.\",\n                        subtaskId,\n                        splits);\n            }\n        }\n    }\n\n    @Override\n    public int currentUnassignedSplitSize() {\n        return pendingSplit.size();\n    }\n\n    @Override\n    public void registerReader(int subtaskId) {\n        log.debug(\"Register reader {} to IoTDBSourceSplitEnumerator.\", subtaskId);\n        if (!pendingSplit.isEmpty()) {\n            assignSplit(Collections.singletonList(subtaskId));\n        }","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-iotdb-v2/src/main/java/org/apache/seatunnel/connectors/seatunnel/iotdbv2/source/IoTDBv2SourceSplitEnumerator.java#L177-L213","documentation":"IoTDBv2SourceSplitEnumerator.addSplitsBack logs this warning when splits are returned from a reader whose subtask ID is not in context.registeredReaders(); the enumerator keeps them pending and skips immediate assignment. It protects against assigning to readers the coordinator doesn't know about during failover or restore races.","triggerScenarios":"addSplitsBack called for subtaskId before that reader (re)registers with the SourceSplitCoordinator — typical during reader failure recovery or checkpoint restore.","commonSituations":"Node failure during IoTDB v2 (session-based) reads; job restart from checkpoint with enumerator recovering splits first; slow reader startup relative to coordinator recovery.","solutions":["No immediate action — splits are pending and assigned after reader registration","Check logs that the reader successfully registers after restart; restart the job if it stays stuck","Stabilize the cluster to avoid repeated reader failovers","Confirm no custom code bypasses the standard reader registration handshake"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Rely on the pending-splits mechanism; verify assignment resumes after reader registration","Watch for repeated warnings indicating stuck readers and restart if needed","Stabilize workers running IoTDB readers","Exercise failover in a staging environment before production"],"tags":["iotdb","source","split-assignment","reader-registration"],"backgroundTag":"invalid-state-transition","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}