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
- Reopen the stream at the desired offset (constructor variant taking a streamOffset) instead of seeking
- Fall back to skip-based forward navigation when only forward movement is needed
- 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
- For encrypted sequential sources, reopen at an offset instead of seeking
- Read large files front-to-back so seeks never target outside the decrypted window
- Know your underlying stream type before enabling seek-driven parsers on encrypted data
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
- ${className} does not support seekToNewSource.
- ${className} does not support positioned read.
- ${className} does not support positioned reads with byte buf
- ${className} does not support positioned readFully.
- Cannot seek to a negative offset
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/2becfd048a2ee8b7.
Report an issue: GitHub.