apache/hadoop · error · UnsupportedOperationException

seek operations are unsupported by the internal stream

Error message

seek operations are unsupported by the internal stream

What it means

ThrottledInputStream delegates seek()/getPos() to the wrapped raw stream only after checkSeekable() confirms it implements org.apache.hadoop.fs.Seekable. If the underlying stream is not Seekable (e.g. a plain HTTP/object-store input stream), calling seek or any position-dependent path raises this UnsupportedOperationException before any delegation occurs.

Source

Thrown at hadoop-tools/hadoop-distcp/src/main/java/org/apache/hadoop/tools/util/ThrottledInputStream.java:151

   */
  public long getTotalSleepTime() {
    return totalSleepTime;
  }

  /** {@inheritDoc} */
  @Override
  public String toString() {
    return "ThrottledInputStream{" +
        "bytesRead=" + bytesRead +
        ", maxBytesPerSec=" + maxBytesPerSec +
        ", bytesPerSec=" + getBytesPerSec() +
        ", totalSleepTime=" + totalSleepTime +
        '}';
  }

  private void checkSeekable() throws IOException {
    if (!(rawStream instanceof Seekable)) {
      throw new UnsupportedOperationException(
          "seek operations are unsupported by the internal stream");
    }
  }

  @Override
  public void seek(long pos) throws IOException {
    checkSeekable();
    ((Seekable) rawStream).seek(pos);
  }

  @Override
  public long getPos() throws IOException {
    checkSeekable();
    return ((Seekable) rawStream).getPos();
  }

  @Override
  public boolean seekToNewSource(long targetPos) throws IOException {

View on GitHub (pinned to 2add963021)

Solutions

  1. Test the raw stream with 'instanceof Seekable' before wrapping or calling seek
  2. Open files through a filesystem returning seekable streams (HDFS), or buffer the data locally when random access is needed
  3. Restructure to sequential reads: close and re-open the stream at the required offset instead of seeking
  4. Pass a Seekable-capable stream into ThrottledInputStream whenever positioning is required

Example fix

// before
InputStream raw = fs.open(path);          // connector stream, not Seekable
ThrottledInputStream in = new ThrottledInputStream(raw, 10 * 1024 * 1024);
in.seek(4096);                            // UnsupportedOperationException

// after
InputStream raw = fs.open(path);
ThrottledInputStream in = new ThrottledInputStream(raw, 10 * 1024 * 1024);
if (raw instanceof Seekable) {
  in.seek(4096);
} else {
  in.close();
  try (InputStream at = openAtOffset(path, 4096)) {  // re-open positioned
    /* sequential read */
  }
}
Defensive patterns

Strategy: type-guard

Validate before calling

// guard before any positioning call
if (!(rawStream instanceof Seekable)) {
  throw new UnsupportedOperationException(
      "positioning needs a seekable stream, got: " + rawStream.getClass());
}

Type guard

static boolean isSeekable(InputStream in) {
  return in instanceof Seekable;
}

Prevention

When it happens

Trigger: Wrapping a non-seekable raw stream in ThrottledInputStream and then calling seek() or getPos()-dependent flows; position-based reads (such as RetriableFileCopyCommand's offset copies) running against connectors whose streams only support sequential reads.

Common situations: Library code assuming FileSystem.open() always yields a seekable stream; S3A/HTTP-backed input streams; custom tools reusing distcp's ThrottledInputStream with arbitrary streams.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/c0bba5a9685b143d. Report an issue: GitHub.