{"record":{"id":"9ab335f968c59606","repo":"apache/seatunnel","slug":"the-thread-was-interrupted-while-waiting-for-a-fet","errorCode":null,"errorMessage":"The thread was interrupted while waiting for a fetcher task.","messagePattern":"The thread was interrupted while waiting for a fetcher task\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-common/src/main/java/org/apache/seatunnel/connectors/seatunnel/common/source/reader/fetcher/SplitFetcher.java","lineNumber":203,"sourceCode":"                            \"Unsafe invoke, the current thread[%s] has not acquired the lock[%s].\",\n                            Thread.currentThread().getName(), this.lock.toString()));\n        }\n\n        try {\n            if (!taskQueue.isEmpty()) {\n                // execute tasks in taskQueue first\n                return taskQueue.poll();\n            } else if (!assignedSplits.isEmpty()) {\n                // use fallback task = fetch if there is at least one split\n                return fetchTask;\n            } else {\n                // nothing to do, wait for signal\n                nonEmpty.await();\n                return taskQueue.poll();\n            }\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new RuntimeException(\n                    \"The thread was interrupted while waiting for a fetcher task.\");\n        }\n    }\n\n    private void wakeUpUnsafe(boolean taskOnly) {\n        if (!lock.isHeldByCurrentThread()) {\n            throw new RuntimeException(\n                    String.format(\n                            \"Unsafe invoke, the current thread[%s] has not acquired the lock[%s].\",\n                            Thread.currentThread().getName(), this.lock.toString()));\n        }\n\n        SplitFetcherTask currentTask = runningTask;\n        if (currentTask != null) {\n            log.debug(\"Waking up running task {}\", currentTask);\n            currentTask.wakeUp();\n        } else if (!taskOnly) {\n            log.debug(\"Waking up fetcher thread.\");","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-common/src/main/java/org/apache/seatunnel/connectors/seatunnel/common/source/reader/fetcher/SplitFetcher.java#L185-L221","documentation":"getNextTaskUnsafe waits on the task queue's condition (nonEmpty.await()) when no task is queued. If the waiting thread is interrupted, it re-interrupts itself and throws this RuntimeException so the fetcher run loop terminates deliberately rather than silently resuming with a possibly empty poll().","triggerScenarios":"The fetcher thread blocked in nonEmpty.await() inside getNextTaskUnsafe receives Thread.interrupt() — normally during shutdownRequested handling, cancellation, or when another thread calls interrupt() on the fetcher thread.","commonSituations":"Job cancellation while the fetcher idles waiting for splits; executor shutdownNow() interrupting fetcher threads; race where shutdown happens before a task is enqueued; test code interrupting threads.","solutions":["Verify this occurred during shutdown/cancellation — if so it is expected and benign; check job shutdown logs","If unexpected, audit code that interrupts the fetcher thread (executor.shutdownNow, custom cancel logic)","Ensure shutdown() uses wakeUp/shutdownRequested signaling instead of raw interrupt to stop idle fetchers","Check for races where SplitFetcherManager.close() runs while splits are still being added — order shutdown after split assignment"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check shutdown state before interpreting interruption\nif (splitFetcherManager.isClosed()) {\n    LOG.info(\"fetcher interrupted as part of shutdown; expected\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    reader.pollNext(...);\n} catch (RuntimeException e) {\n    if (\"The thread was interrupted while waiting for a fetcher task.\".equals(e.getMessage())\n            && shuttingDown.get()) {\n        LOG.info(\"benign interrupt during shutdown\");\n        return;\n    }\n    throw e;\n}","preventionTips":["Use wakeUp()/shutdown signaling rather than raw thread.interrupt() to stop fetchers","Order shutdown before returning from source reader close to avoid idle-wait interrupts","Avoid executor.shutdownNow() on fetcher executors while splits are pending","Treat this error as expected during cancellation; alert only when it appears in steady-state runs"],"tags":["concurrency","interruption","fetcher","thread"],"backgroundTag":"thread-interrupted","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"}