{"record":{"id":"e62d6c6fd8fbec64","repo":"apache/hadoop","slug":"classname-does-not-support-positioned-readfully","errorCode":null,"errorMessage":"${className} does not support positioned readFully.","messagePattern":"(.+?) does not support positioned readFully\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java","lineNumber":507,"sourceCode":"        } finally {\n          localPadding = afterDecryption(localDecryptor, localInBuffer,\n                                         filePosition + length, localIV);\n        }\n      }\n    } finally {\n      returnBuffer(localInBuffer);\n      returnBuffer(localOutBuffer);\n      returnDecryptor(localDecryptor);\n    }\n  }\n\n  /** Positioned read fully. It is thread-safe */\n  @Override\n  public void readFully(long position, byte[] buffer, int offset, int length)\n      throws IOException {\n    checkStream();\n    if (!(in instanceof PositionedReadable)) {\n      throw new UnsupportedOperationException(in.getClass().getCanonicalName()\n          + \" does not support positioned readFully.\");\n    }\n    ((PositionedReadable) in).readFully(position, buffer, offset, length);\n    if (length > 0) {\n      // This operation does not change the current offset of the file\n      decrypt(position, buffer, offset, length);\n    }\n  }\n\n  @Override\n  public void readFully(long position, byte[] buffer) throws IOException {\n    readFully(position, buffer, 0, buffer.length);\n  }\n\n  /** Seek to a position. */\n  @Override\n  public void seek(long pos) throws IOException {\n    if (pos < 0) {","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java#L489-L525","documentation":"The byte[] positioned readFully on CryptoInputStream requires `in instanceof PositionedReadable`. If the wrapped stream supports only sequential reads, UnsupportedOperationException naming the wrapped class is thrown up front, before any decryption happens.","triggerScenarios":"readFully(position, buffer, offset, length) on a CryptoInputStream wrapping a non-PositionedReadable stream — e.g. wrapped local streams, some connector streams, or mocks.","commonSituations":"Split-based record readers doing positional readFully on encrypted files backed by incompatible stream types; libraries assuming every FSDataInputStream supports positional reads.","solutions":["Use seek() plus sequential readFully when the stream is Seekable","Wrap the source stream in a PositionedReadable implementation before building the CryptoInputStream","Catch UnsupportedOperationException and use a sequential copy strategy"],"exampleFix":"// before\ncryptoIn.readFully(pos, buf, 0, len); // UOE without PositionedReadable\n\n// after\ntry {\n  cryptoIn.readFully(pos, buf, 0, len);\n} catch (UnsupportedOperationException e) {\n  cryptoIn.seek(pos);\n  IOUtils.readFully(cryptoIn, buf, 0, len);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  in.readFully(pos, buf, off, len);\n} catch (UnsupportedOperationException e) {\n  in.seek(pos);\n  IOUtils.readFully(in, buf, off, len);\n}","preventionTips":["Do not assume FSDataInputStream positional APIs work on every FileSystem; probe once per filesystem type and cache the result","Prefer seek+sequential reads in reader loops that already track a current offset","For custom streams, implement PositionedReadable so wrapped/encrypted views inherit the capability"],"tags":["crypto","hdfs","stream","positioned-read","hadoop"],"backgroundTag":"unsupported-stream-operation","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}