{"record":{"id":"a93e8954d64587cc","repo":"apache/flink","slug":"stream-closed-a93e89","errorCode":null,"errorMessage":"Stream closed.","messagePattern":"Stream closed\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/core/fs/RefCountedFile.java","lineNumber":80,"sourceCode":"        if (references.decrementAndGet() == 0) {\n            return tryClose();\n        }\n        return false;\n    }\n\n    private boolean tryClose() {\n        try {\n            Files.deleteIfExists(file.toPath());\n            return true;\n        } catch (Throwable t) {\n            ExceptionUtils.rethrowIfFatalError(t);\n        }\n        return false;\n    }\n\n    private void requireOpened() throws IOException {\n        if (closed) {\n            throw new IOException(\"Stream closed.\");\n        }\n    }\n\n    public int getReferenceCounter() {\n        return references.get();\n    }\n}\n","sourceCodeStart":62,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/core/fs/RefCountedFile.java#L62-L88","documentation":"Thrown by RefCountedFile.requireOpened() when an operation is attempted on a temp file reference whose `closed` flag is true. RefCountedFile is the reference-counted handle to the temp file backing recoverable writers; operating after close violates the lifecycle contract.","triggerScenarios":"Calling getOutputStream/write/getPos (or any guarded op) on a RefCountedFile after release() decremented references to zero and closed it, or after an explicit close.","commonSituations":"Reference-counting misuse: releasing the last reference then attempting to use the file; concurrent release+write during cancellation; a bug where the same handle is shared and one owner closes while another writes.","solutions":["Audit retain()/release() balance: every retain must have a matching release, and operations must happen before the final release.","After release(), drop the reference so it cannot be reused.","Ensure single-ownership of the RefCountedFile handle or use proper retain before sharing across threads.","In cancellation paths, drain outstanding writes before releasing."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"void useRefCountedFile(RefCountedFile f) throws IOException {\n    if (f.getReferenceCounter() <= 0) throw new IllegalStateException(\"file already released\");\n    // operate on f\n}","typeGuard":null,"tryCatchPattern":"try {\n    file.getPos();\n} catch (IOException e) {\n    if (\"Stream closed.\".equals(e.getMessage())) { /* handle released file */ return; }\n    throw e;\n}","preventionTips":["Pair every retain() with a release() in the same scope.","After the final release(), null the reference.","Avoid sharing RefCountedFile across threads without an explicit retain."],"tags":["filesystem","reference-counting","resource-lifecycle","use-after-close"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}