apache/beam · warning · UnsupportedOperationException
Caller does not own the underlying input stream and should…
Error message
Caller does not own the underlying input stream and should not call close().
What it means
UnownedInputStream wraps an InputStream that the wrapper does not own, so close() deliberately throws UnsupportedOperationException. The library is enforcing resource ownership: closing the wrapper would close a stream the caller does not own, breaking whoever actually manages it.
Solutions
- Remove close() from the UnownedInputStream; close the underlying owned stream instead.
- Restructure so try-with-resources wraps the original owned InputStream, not the wrapper.
- If a consuming API demands a closeable stream, wrap with a CloseableInputStream (e.g. Guava's) or use ByteStreams.limit/Joiner semantics that don't propagate close.
- If you truly own the underlying stream and want close to work, pass it directly rather than through UnownedInputStream.
Example fix
// before
try (InputStream in = new UnownedInputStream(ownedStream)) {
readAll(in);
} // throws UnsupportedOperationException
// after
try (InputStream owned = ownedStream) {
InputStream in = new UnownedInputStream(owned);
readAll(in);
} // owned stream closed by caller-owned resource Defensive patterns
Strategy: try-catch
Type guard
boolean safeToClose(InputStream in) {
return !(in instanceof UnownedInputStream);
} Try / catch
try {
in.close();
} catch (UnsupportedOperationException e) {
// expected: caller does not own the stream; close the owned stream elsewhere
} Prevention
- Never put UnownedInputStream in try-with-resources.
- Close the stream you created, not wrappers around someone else's.
- Check for UnownedInputStream before delegating close in utility code.
When it happens
Trigger: Calling close() on an UnownedInputStream obtained e.g. from Avro/GCS readable byte channel wrappers, typically via try-with-resources on the wrapper instead of the owned stream, or when a utility auto-closes streams it is handed.
Common situations: Using try-with-resources around an UnownedInputStream, passing the wrapper to code that closes its input (e.g. IOUtils.closeQuietly), or refactoring code that previously wrapped an owned FileInputStream.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Caller does not own the underlying input stream and should…
- Caller does not own the underlying input stream and should…
- Caller does not own the underlying output stream and…
- Can not get unique key from solr
- Delimiter must be a non-empty bytes sequence.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/125b765962c8aecf.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/UnownedInputStream.java:44
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* A {@link OutputStream} wrapper which protects against the user attempting to modify the
* underlying stream by closing it or using mark.
*/
@Internal
public class UnownedInputStream extends FilterInputStream {
public UnownedInputStream(InputStream delegate) {
super(delegate);
}
InputStream getWrappedStream() {
return in;
}
@Override
public void close() throws IOException {
throw new UnsupportedOperationException(
"Caller does not own the underlying input stream " + " and should not call close().");
}
@Override
public boolean equals(@Nullable Object obj) {
return obj instanceof UnownedInputStream && ((UnownedInputStream) obj).in.equals(in);
}
@Override
public int hashCode() {
return in.hashCode();
}
@SuppressWarnings("UnsynchronizedOverridesSynchronized")
@Override
public void mark(int readlimit) {
throw new UnsupportedOperationException(
"Caller does not own the underlying input stream " + " and should not call mark().");View on GitHub (pinned to 12126d8942)