{"record":{"id":"85865514254ca49a","repo":"apache/hadoop","slug":"mark-reset-not-supported","errorCode":null,"errorMessage":"Mark/reset not supported","messagePattern":"Mark/reset not supported","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java","lineNumber":690,"sourceCode":"  @Override\n  public int available() throws IOException {\n    checkStream();\n    \n    return in.available() + outBuffer.remaining();\n  }\n\n  @Override\n  public boolean markSupported() {\n    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,","sourceCodeStart":672,"sourceCodeEnd":708,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoInputStream.java#L672-L708","documentation":"CryptoInputStream.markSupported() returns false and mark(int) is a silent no-op, because decryptors are stateful (stream offset, IV progression) so a mark/reset cannot be honored even when the wrapped stream supports it. reset() therefore always throws IOException(\"Mark/reset not supported\").","triggerScenarios":"Calling reset() on any CryptoInputStream — the check is unconditional, not an instanceof probe of the inner stream; mark-then-reset format sniffing in parsers hits this on encrypted streams.","commonSituations":"Libraries that branch on InputStream marking (format detectors, serialization frameworks) applied to encrypted HDFS data; code ported from plain streams that assumed mark/reset was available.","solutions":["Guard with if (in.markSupported()) before any mark/reset and take an alternate path when false","Read the header bytes into a byte[] and parse from memory instead of mark/probe/rewind","Reopen the stream at the original offset instead of reset()"],"exampleFix":"// before\nin.mark(64);\nprobeHeader(in);\nin.reset(); // IOException: Mark/reset not supported\n\n// after\nbyte[] header = new byte[64];\nIOUtils.readFully(in, header, 0, header.length); // no rewind needed\nprobeHeader(header);","handlingStrategy":"validation","validationCode":"if (in.markSupported()) {\n  in.mark(readLimit);\n  try { probe(in); } finally { in.reset(); }\n} else {\n  // buffered/manual strategy: read header into byte[] and parse from memory\n}","typeGuard":null,"tryCatchPattern":"try {\n  in.reset();\n} catch (IOException e) {\n  if (\"Mark/reset not supported\".equals(e.getMessage())) {\n    in = reopenAt(savedPos); // recover by reopening\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always branch on markSupported() before mark/reset in format-sniffing code","Snapshot headers into byte[] instead of relying on stream rewind","Remember CryptoInputStream never supports mark/reset, regardless of the wrapped stream"],"tags":["crypto","stream","mark-reset","hadoop"],"backgroundTag":"mark-reset-not-supported","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}