{"record":{"id":"70f5ffafd21291a4","repo":"apache/hadoop","slug":"classname-does-not-support-seektonewsource","errorCode":null,"errorMessage":"${className} does not support seekToNewSource.","messagePattern":"(.+?) does not support seekToNewSource\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java","lineNumber":699,"sourceCode":"    return false;\n  }\n  \n  @Override\n  public void mark(int readLimit) {\n  }\n  \n  @Override\n  public void reset() throws IOException {\n    throw new IOException(\"Mark/reset not supported\");\n  }\n\n  @Override\n  public boolean seekToNewSource(long targetPos) throws IOException {\n    Preconditions.checkArgument(targetPos >= 0, \n        \"Cannot seek to negative offset.\");\n    checkStream();\n    if (!(in instanceof Seekable)) {\n      throw new UnsupportedOperationException(in.getClass().getCanonicalName()\n          + \" does not support seekToNewSource.\");\n    }\n    boolean result = ((Seekable) in).seekToNewSource(targetPos);\n    resetStreamOffset(targetPos);\n    return result;\n  }\n\n  @Override\n  public ByteBuffer read(ByteBufferPool bufferPool, int maxLength,\n      EnumSet<ReadOption> opts) throws IOException,\n      UnsupportedOperationException {\n    checkStream();\n    if (outBuffer.remaining() > 0) {\n      if (!(in instanceof Seekable)) {\n        throw new UnsupportedOperationException(in.getClass().getCanonicalName()\n            + \" does not support seek.\");\n      }\n      // Have some decrypted data unread, need to reset.","sourceCodeStart":681,"sourceCodeEnd":717,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java#L681-L717","documentation":"seekToNewSource(long) is the read-replica-failure fallback API. CryptoInputStream first rejects negative targetPos via Preconditions, then requires `in instanceof Seekable` and throws UnsupportedOperationException naming the wrapped class otherwise. So on encrypted streams this failover path exists only when the inner stream is Seekable.","triggerScenarios":"Calling seekToNewSource() on encrypted files when the underlying stream is not Seekable; client retry logic attempting to switch replicas after a checksum/read error.","commonSituations":"Custom retry layers in InputFormats implementing replica failover; unit tests with mock inner streams that only implement InputStream.","solutions":["Skip the alternate-replica fallback for encrypted reads and reopen the stream instead","Catch UnsupportedOperationException and re-open the file rather than switching source","Ensure the wrapped stream implements Seekable if you control the stream implementation"],"exampleFix":"// before\nboolean moved = fsIn.seekToNewSource(pos); // UOE when inner stream not Seekable\n\n// after\ntry {\n  boolean moved = fsIn.seekToNewSource(pos);\n} catch (UnsupportedOperationException e) {\n  fsIn = fs.open(path); // reopen as the recovery path\n  fsIn.seek(pos);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  moved = fsIn.seekToNewSource(pos);\n} catch (UnsupportedOperationException e) {\n  fsIn = fs.open(path); // reopen as the failover path\n  fsIn.seek(pos);\n}","preventionTips":["Treat seekToNewSource as optional failover, not a required step in read retry logic","Validate targetPos >= 0 before calling (Preconditions also rejects negatives)","Design recovery paths around reopen rather than replica switching for encrypted files"],"tags":["crypto","hdfs","stream","seek","failover","hadoop"],"backgroundTag":"unsupported-stream-operation","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}