apache/beam · error · UnsupportedOperationException

GcsSeekableByteChannel are read-only and does not support wr

Error message

GcsSeekableByteChannel are read-only and does not support writing.

What it means

GcsSeekableByteChannel returned by GcsUtilV2 opens GCS objects in read-only mode; any attempt to write, position for write, or truncate throws UnsupportedOperationException. GCS objects are immutable through this channel abstraction, so writes are intentionally unsupported rather than emulated.

Source

Thrown at sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/GcsUtilV2.java:545

    @Override
    public long position() throws IOException {
      return this.position;
    }

    @Override
    public long size() throws IOException {
      return size;
    }

    @Override
    public SeekableByteChannel truncate(long size) throws IOException {
      throw new UnsupportedOperationException(
          "GcsSeekableByteChannels are read-only and cannot be truncated.");
    }

    @Override
    public int write(ByteBuffer src) throws IOException {
      throw new UnsupportedOperationException(
          "GcsSeekableByteChannel are read-only and does not support writing.");
    }

    @Override
    public boolean isOpen() {
      return reader.isOpen();
    }

    @Override
    public void close() throws IOException {
      if (isOpen()) {
        reader.close();
      }
    }
  }

  public SeekableByteChannel open(GcsPath path, BlobSourceOption... sourceOptions)
      throws IOException {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Rewrite the code to only read from the GCS channel
  2. To modify a GCS object, download it, modify locally, and upload a new object (or use the GCS rewrite/compose APIs instead)
  3. Use WriteChannels from GcsUtil/GcsOptions (create(GcsPath)) rather than open() when writing is intended

Example fix

// before
SeekableByteChannel ch = gcsUtil.open(path);
ch.write(ByteBuffer.wrap(data)); // throws
// after
try (WriteChannel wc = gcsUtil.create(path)) {
  wc.write(ByteBuffer.wrap(data));
}
Defensive patterns

Strategy: validation

Validate before calling

if (channel instanceof GcsSeekableByteChannel || gcsPath != null && channelMode == Mode.READ) { /* never call write/truncate */ }

Type guard

boolean isWritableChannel(SeekableByteChannel ch) { return !(ch instanceof GcsSeekableByteChannel); }

Prevention

When it happens

Trigger: Calling write(ByteBuffer), truncate(long), or position(long) with a value larger than the object size on a channel obtained via GcsUtilV2.open(GcsPath).

Common situations: Code written against java.nio.FileChannel semantics (read-modify-write of a remote file) reused on a GCS path; file-copy utilities that open channels with READ|WRITE options.

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/a9a29630489dcf0f. Report an issue: GitHub.