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

  1. Remove close() from the UnownedInputStream; close the underlying owned stream instead.
  2. Restructure so try-with-resources wraps the original owned InputStream, not the wrapper.
  3. 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.
  4. 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

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


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)