apache/hadoop · error · UnsupportedOperationException

${className} does not support seek.

Error message

${className} does not support seek.

What it means

CryptoInputStream.seek() can satisfy a target cheaply only when it falls inside the already-decrypted outBuffer window (streamOffset - outBuffer.remaining() .. streamOffset). Otherwise it must reposition the wrapped stream, which requires `in instanceof Seekable`; a non-Seekable inner stream triggers UnsupportedOperationException with the wrapped class name.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java:540

  /** Seek to a position. */
  @Override
  public void seek(long pos) throws IOException {
    if (pos < 0) {
      throw new EOFException(FSExceptionMessages.NEGATIVE_SEEK);
    }
    checkStream();
    /*
     * If data of target pos in the underlying stream has already been read
     * and decrypted in outBuffer, we just need to re-position outBuffer.
     */
    if (pos <= streamOffset && pos >= (streamOffset - outBuffer.remaining())) {
      int forward = (int) (pos - (streamOffset - outBuffer.remaining()));
      if (forward > 0) {
        outBuffer.position(outBuffer.position() + forward);
      }
    } else {
      if (!(in instanceof Seekable)) {
        throw new UnsupportedOperationException(in.getClass().getCanonicalName()
            + " does not support seek.");
      }
      ((Seekable) in).seek(pos);
      resetStreamOffset(pos);
    }
  }
  
  /** Skip n bytes */
  @Override
  public long skip(long n) throws IOException {
    Preconditions.checkArgument(n >= 0, "Negative skip length.");
    checkStream();
    
    if (n == 0) {
      return 0;
    } else if (n <= outBuffer.remaining()) {
      int pos = outBuffer.position() + (int) n;
      outBuffer.position(pos);

View on GitHub (pinned to 2add963021)

Solutions

  1. Reopen the stream at the desired offset (constructor variant taking a streamOffset) instead of seeking
  2. Fall back to skip-based forward navigation when only forward movement is needed
  3. Wrap the source stream in a Seekable implementation before constructing the CryptoInputStream

Example fix

// before
cryptoIn.seek(newPos); // UOE when inner stream is not Seekable

// after
// close and reopen at the offset for encrypted sequential sources
cryptoIn.close();
CryptoInputStream fresh = new CryptoInputStream(
    sourceFactory.open(), codec, bufferSize, key, iv, newPos /* streamOffset */);
Defensive patterns

Strategy: try-catch

Try / catch

try {
  in.seek(pos);
} catch (UnsupportedOperationException e) {
  // inner stream not Seekable: reopen at the offset
  in.close();
  in = openStreamAt(pos);
}

Prevention

When it happens

Trigger: Calling seek() to a position outside the buffered decrypted range on a CryptoInputStream over a sequential-only inner stream; note the read(ByteBufferPool,...) path also hits this check when discarding leftover decrypted data.

Common situations: Seek-driven readers (record readers, format parsers) on encrypted files where the underlying stream cannot seek (some object-store connectors, wrapped test streams).

Related errors


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