{"record":{"id":"a4c9ed6c11665b0b","repo":"apache/iceberg","slug":"an-error-occurred-while-closing-the-stream","errorCode":null,"errorMessage":"An error occurred while closing the stream","messagePattern":"An error occurred while closing the stream","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"aws/src/main/java/org/apache/iceberg/aws/s3/S3InputStream.java","lineNumber":282,"sourceCode":"    }\n  }\n\n  @VisibleForTesting\n  void resetForRetry() throws IOException {\n    openStream(true);\n  }\n\n  private void closeStream(boolean closeQuietly) throws IOException {\n    if (stream != null) {\n      // if we aren't at the end of the stream, and the stream is abortable, then\n      // call abort() so we don't read the remaining data with the Apache HTTP client\n      abortStream();\n      try {\n        stream.close();\n      } catch (IOException e) {\n        if (closeQuietly) {\n          stream = null;\n          LOG.warn(\"An error occurred while closing the stream\", e);\n          return;\n        }\n\n        // the Apache HTTP client will throw a ConnectionClosedException\n        // when closing an aborted stream, which is expected\n        if (!e.getClass().getSimpleName().equals(\"ConnectionClosedException\")) {\n          throw e;\n        }\n      }\n      stream = null;\n    }\n  }\n\n  private void abortStream() {\n    try {\n      if (stream instanceof Abortable && stream.read() != -1) {\n        ((Abortable) stream).abort();\n      }","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/aws/src/main/java/org/apache/iceberg/aws/s3/S3InputStream.java#L264-L300","documentation":"S3InputStream.closeStream aborts and closes the underlying S3 stream; an IOException here is either swallowed with a WARN ('An error occurred while closing the stream') when closeQuietly is set, or rethrown/wrapped unless it is the Apache client's ConnectionClosedException, which is expected after aborting a stream. Developers typically see this as a noisy WARN during normal abort-driven closes or a wrapped IOException when a real close failure occurs.","triggerScenarios":"Closing an S3InputStream (try-with-resources or explicit close) whose stream was aborted mid-read (e.g. after read failures or early close), or a stream close that fails at the HTTP client level with an IOException other than ConnectionClosedException.","commonSituations":"Aborting reads of large S3 objects (seek/skip past ranges) producing expected ConnectionClosedException noise; stale/closed connections from long-lived readers; aggressive connection pool eviction; reading objects with short HTTP timeouts then closing.","solutions":["Enable/set closeQuietly=true (S3FileIO property aws.s3.stream.close-quietly or constructor flag) if the WARN is noise from aborted streams","Confirm the logged exception is ConnectionClosedException — that is expected after abort and can be ignored","If a different IOException is thrown, check S3 endpoint connectivity, timeouts, and connection pool settings","Retry the read from a fresh stream; the failed stream is already nulled out on quiet close"],"exampleFix":"// before\ntry (S3InputStream in = new S3InputStream(io, bucket, key)) { ... } // noisy close errors after abort\n// after\nS3InputStream in = new S3InputStream(io, bucket, key, /*closeQuietly=*/true);\ntry { ... } finally { in.close(); } // abort-close IOExceptions logged as WARN, not thrown","handlingStrategy":"try-catch","validationCode":"// ensure the reader is closed exactly once and not re-used after close\nif (in == null || closed) skipClose(); // S3InputStream nulls stream on quiet close","typeGuard":null,"tryCatchPattern":"try {\n  in.close();\n} catch (IOException e) {\n  if (\"ConnectionClosedException\".equals(e.getClass().getSimpleName())) {\n    // expected after aborting an S3 stream — ignore\n  } else {\n    LOG.warn(\"real stream close failure\", e);\n  }\n}","preventionTips":["Set closeQuietly=true when streams are regularly aborted mid-read","Treat ConnectionClosedException after abort as normal, not a defect","Check S3 timeouts/pool settings if non-ConnectionClosed IOExceptions appear","Use try-with-resources so streams never leak and double-close is avoided"],"tags":["aws","s3","io","stream-close"],"backgroundTag":"stream-close-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}