{"record":{"id":"72d409aa03e42fe1","repo":"apache/iceberg","slug":"unclosed-output-stream-created-by","errorCode":null,"errorMessage":"Unclosed output stream created by:\n\t{}","messagePattern":"Unclosed output stream created by:\n\t(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"aliyun/src/main/java/org/apache/iceberg/aliyun/oss/OSSOutputStream.java","lineNumber":174,"sourceCode":"    PutObjectRequest request =\n        new PutObjectRequest(uri.bucket(), uri.key(), contentStream, metadata);\n    client.putObject(request);\n  }\n\n  private void cleanUpStagingFiles() {\n    if (!currentStagingFile.delete()) {\n      LOG.warn(\"Failed to delete staging file: {}\", currentStagingFile);\n    }\n  }\n\n  @SuppressWarnings({\"checkstyle:NoFinalizer\", \"Finalize\", \"deprecation\"})\n  @Override\n  protected void finalize() throws Throwable {\n    super.finalize();\n    if (!closed) {\n      close(); // releasing resources is more important than printing the warning.\n      String trace = Joiner.on(\"\\n\\t\").join(Arrays.copyOfRange(createStack, 1, createStack.length));\n      LOG.warn(\"Unclosed output stream created by:\\n\\t{}\", trace);\n    }\n  }\n}\n","sourceCodeStart":156,"sourceCodeEnd":178,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/aliyun/src/main/java/org/apache/iceberg/aliyun/oss/OSSOutputStream.java#L156-L178","documentation":"This is a diagnostic warning (not an exception thrown to the caller) emitted from OSSOutputStream.finalize() when the garbage collector reclaims an output stream that was never closed. Iceberg detects the leak via the 'closed' flag and closes the stream defensively to release the underlying OSS resources, while logging the stack trace of where the stream was created so the developer can fix the missing close().","triggerScenarios":"An OSSOutputStream created by the Aliyun OSS FileIO write path was garbage collected without close() ever being called — e.g. a caller obtained an OutputStream from OSSOutputFile.create() and dropped it without closing, or an exception was thrown mid-write and no try-with-resources/finally cleanup ran.","commonSituations":"Writing a data/metadata file to OSS with an unclosed stream during an error path; forgetting try-with-resources around the OutputStream returned by a FileIO write; frameworks that abort a task without closing task-writer streams; long-running Spark/Flink jobs where leaked streams accumulate until GC triggers the warning.","solutions":["Wrap the OutputStream from FileIO.create(...) in try-with-resources so close() is always called, even on exception.","Audit the code path identified by the logged 'created by' stack trace and add explicit close() in a finally block where try-with-resources is not possible.","If the warning appears under load, check writer/task cleanup in your engine integration (e.g. task abort logic) to ensure writers are closed on failure.","Reproduce with a smaller workload and monitor GC logs to confirm no streams are being dropped."],"exampleFix":"// before\nOutputStream out = io.newOutputFile(path).create();\nout.write(data);\n\n// after\ntry (OutputStream out = io.newOutputFile(path).create()) {\n  out.write(data);\n}","handlingStrategy":"validation","validationCode":"// Ensure every OSS/FileIO output stream is closed; prefer try-with-resources.\n// Pre-flight check in code review: search for '.create()' on OutputFile and confirm each is in try-with-resources.\ntry (OutputStream out = io.newOutputFile(path).create()) {\n  // write\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use try-with-resources for OutputStreams from FileIO/OSSOutputFile.","Never store OutputStreams in fields without a close lifecycle (implement AutoCloseable on owning classes).","In task-abort/error paths, explicitly close all opened writers.","Treat 'Unclosed output stream' warnings as actionable: follow the logged creation stack trace."],"tags":["resource-leak","aliyun","oss","output-stream","finalize","gc-warning"],"backgroundTag":"unclosed-resource-leak","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}