{"record":{"id":"37c271eae1080fb3","repo":"apache/hadoop","slug":"classname-does-not-support-release-buffer","errorCode":null,"errorMessage":"${className} does not support release buffer.","messagePattern":"(.+?) does not support release buffer\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java","lineNumber":741,"sourceCode":"          + \" does not support enhanced byte buffer access.\");\n    }\n    final ByteBuffer buffer = ((HasEnhancedByteBufferAccess) in).\n        read(bufferPool, maxLength, opts);\n    if (buffer != null) {\n      final int n = buffer.remaining();\n      if (n > 0) {\n        streamOffset += buffer.remaining(); // Read n bytes\n        final int pos = buffer.position();\n        decrypt(buffer, n, pos);\n      }\n    }\n    return buffer;\n  }\n\n  @Override\n  public void releaseBuffer(ByteBuffer buffer) {\n    if (!(in instanceof HasEnhancedByteBufferAccess)) {\n      throw new UnsupportedOperationException(in.getClass().getCanonicalName()\n          + \" does not support release buffer.\");\n    }\n    ((HasEnhancedByteBufferAccess) in).releaseBuffer(buffer);\n  }\n\n  @Override\n  public void setReadahead(Long readahead) throws IOException,\n      UnsupportedOperationException {\n    if (!(in instanceof CanSetReadahead)) {\n      throw new UnsupportedOperationException(in.getClass().getCanonicalName()\n          + \" does not support setting the readahead caching strategy.\");\n    }\n    ((CanSetReadahead) in).setReadahead(readahead);\n  }\n\n  @Override\n  public void setDropBehind(Boolean dropCache) throws IOException,\n      UnsupportedOperationException {","sourceCodeStart":723,"sourceCodeEnd":759,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java#L723-L759","documentation":"releaseBuffer(ByteBuffer) returns pooled buffers to the wrapped stream, so it requires `in instanceof HasEnhancedByteBufferAccess` — the same interface that governs obtaining such buffers. If the inner stream lacks it, UnsupportedOperationException naming the wrapped class is thrown.","triggerScenarios":"Calling releaseBuffer() on a CryptoInputStream that never handed out pooled buffers (inner stream lacks HasEnhancedByteBufferAccess); cleanup paths that release unconditionally after a read fell back to plain byte[] reads.","commonSituations":"Zero-copy readers whose buffer-release code does not track whether the acquisition actually succeeded through the pooled path.","solutions":["Only call releaseBuffer() for buffers actually returned by read(ByteBufferPool,...) on the same stream","Track the acquisition path (pooled vs byte[]) so the release path matches it","Catch UnsupportedOperationException in cleanup code so release failures never mask the primary result"],"exampleFix":"// before\nif (buffer != null) {\n  cryptoIn.releaseBuffer(buffer); // UOE if pooled reads unsupported\n}\n\n// after\nif (buffer != null) {\n  try {\n    cryptoIn.releaseBuffer(buffer);\n  } catch (UnsupportedOperationException e) {\n    // pooled path never active on this stream; nothing to return\n  }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  in.releaseBuffer(buffer);\n} catch (UnsupportedOperationException e) {\n  // pooled path was never active on this stream; nothing to return\n}","preventionTips":["Track whether each buffer came from the pooled API before releasing it","Keep acquisition and release code paths symmetric","Never let cleanup-time release failures mask the primary read result"],"tags":["crypto","stream","bytebuffer","zero-copy","hadoop"],"backgroundTag":"unsupported-stream-operation","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}