{"record":{"id":"faad47acbf9fa534","repo":"apache/iceberg","slug":"unclosed-input-stream-created-by-n-t","errorCode":null,"errorMessage":"Unclosed input stream created by:\\n\\t{}","messagePattern":"Unclosed input stream created by:\\\\n\\\\t(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"aws/src/main/java/org/apache/iceberg/aws/s3/S3InputStream.java","lineNumber":317,"sourceCode":"        ((Abortable) stream).abort();\n      }\n    } catch (Exception e) {\n      LOG.warn(\"An error occurred while aborting the stream\", e);\n    }\n  }\n\n  public void setSkipSize(int skipSize) {\n    this.skipSize = skipSize;\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 input stream created by:\\n\\t{}\", trace);\n    }\n  }\n}\n","sourceCodeStart":299,"sourceCodeEnd":321,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/aws/src/main/java/org/apache/iceberg/aws/s3/S3InputStream.java#L299-L321","documentation":"S3InputStream.finalize() detects input streams that were never close()d before garbage collection. It closes the stream (releasing the S3 connection is prioritized), then logs this warning with the creation stack trace to expose the leak. Leaked streams hold S3 connections/heap buffers until GC.","triggerScenarios":"Code obtains an input stream from S3InputFile.newStream() and never closes it, e.g. early return/exception path skipping close, or a failed parquet/avro read that didn't close its source.","commonSituations":"Manual stream handling without try-with-resources; reader frameworks that abandon streams on parse errors; Spark tasks cancelled mid-read.","solutions":["Wrap all S3InputStream usage in try-with-resources","Close the stream in finally blocks on early-return paths","Use the logged create-stack to find the leaking call site","Prefer higher-level readers (e.g. DataFile readers) that manage stream lifecycle"],"exampleFix":"// before\nInputStream in = inputFile.newStream();\nreturn readHeader(in);\n// after\ntry (InputStream in = inputFile.newStream()) {\n  return readHeader(in);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try (InputStream in = inputFile.newStream()) {\n  // read\n} catch (IOException e) {\n  throw new UncheckedIOException(e);\n} // stream is always closed even on exception","preventionTips":["Use try-with-resources for every newStream() call","Close streams on all early-return and exception paths","Use the create-stack trace in the warning to locate leaks","Prefer wrappers (Parquet/Avro readers) that close sources on failure"],"tags":["resource-leak","stream","s3","finalizer"],"backgroundTag":"resource-not-closed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}