apache/iceberg · warning
Unclosed input stream created by: {}
Error message
Unclosed input stream created by:
{} What it means
OSSInputStream registers its creation stack trace and, in finalize(), if the stream was never closed, it closes it to release the underlying OSSObject and logs a warning showing where the stream was created. This catches leaks — callers who opened stream(...) but never called close() — letting the GC reclaim the resource, while the warning points at the offending call site.
Source
Thrown at aliyun/src/main/java/org/apache/iceberg/aliyun/oss/OSSInputStream.java:167
GetObjectRequest request = new GetObjectRequest(uri.bucket(), uri.key()).withRange(pos, -1);
stream = client.getObject(request).getObjectContent();
}
private void closeStream() throws IOException {
if (stream != null) {
stream.close();
stream = null;
}
}
@SuppressWarnings({"checkstyle:NoFinalizer", "Finalize", "deprecation"})
@Override
protected void finalize() throws Throwable {
super.finalize();
if (!closed) {
close(); // releasing resources is more important than printing the warning
String trace = Joiner.on("\n\t").join(Arrays.copyOfRange(createStack, 1, createStack.length));
LOG.warn("Unclosed input stream created by: \n\t{}", trace);
}
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Wrap every stream in try-with-resources: try (InputStream in = file.newStream()) { ... }.
- Use the 'created by' stack trace in the warning to locate the leaked open call and add close/finally there.
- For conditional reads, close the stream in all branches, including early returns and exceptions.
- Upgrade Iceberg if you see spurious warnings — finalizer-based detection may race; rely on explicit close regardless.
Example fix
// before
InputStream in = file.newStream();
long len = file.getLength();
// after
try (InputStream in = file.newStream()) {
long len = file.getLength();
} Defensive patterns
Strategy: try-catch
Try / catch
try (InputStream in = file.newStream()) {
readAll(in);
} catch (IOException e) {
throw new UncheckedIOException(e);
} // close() guaranteed on all paths — no finalize warning Prevention
- Always use try-with-resources for streams from FileIO.newInputFile().newStream().
- Never store an open InputStream in a long-lived field or cache entry.
- In error paths, close streams in finally rather than letting the exception bypass close.
- Treat any 'Unclosed input stream created by' warning as a real leak to fix at the traced call site, not noise.
When it happens
Trigger: Code calls OSSFileIO.newInputFile().newStream() (or OSSInputFile stream()) and never calls close(), letting the stream become garbage-collectible while still open.
Common situations: Missing try-with-resources around stream reads in custom Avro/Parquet readers; exceptions thrown between open and close without finally; stream stored in a field and forgotten during task cancellation.
Related errors
- Unclosed output stream created by: {}
- Failed to create RRSA OSS client
- Location already exists: %s
- Unable to load metrics class: '{}', falling back to null met
- Failed to delete staging file: {}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c3b21539fb76f49f.
Report an issue: GitHub.