apache/hadoop · error · IllegalStateException

Attempt to examine value multiple times.

Error message

Attempt to examine value multiple times.

What it means

IllegalStateException from Scanner.Entry.getValueStream() when valueChecked is already true. TFile does not cache value bytes; the value region of the current cursor position can be read exactly once. Every value accessor (getValue(byte[]), getValue(byte[], int), getValueStream()) funnels through getValueStream(), so any second access on the same entry trips this guard.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/file/tfile/TFile.java:1917

            return nextOffset - offset;
          } finally {
            dis.close();
          }
        }

        /**
         * Stream access to value. The value part of the key-value pair pointed
         * by the current cursor is not cached and can only be examined once.
         * Calling any of the following functions more than once without moving
         * the cursor will result in exception: {@link #getValue(byte[])},
         * {@link #getValue(byte[], int)}, {@link #getValueStream}.
         * 
         * @return The input stream for reading the value.
         * @throws IOException raised on errors performing I/O.
         */
        public DataInputStream getValueStream() throws IOException {
          if (valueChecked == true) {
            throw new IllegalStateException(
                "Attempt to examine value multiple times.");
          }
          valueChecked = true;
          return valueDataInputStream;
        }

        /**
         * Check whether it is safe to call getValueLength().
         * 
         * @return true if value length is known before hand. Values less than
         *         the chunk size will always have their lengths known before
         *         hand. Values that are written out as a whole (with advertised
         *         length up-front) will always have their lengths known in
         *         read.
         */
        public boolean isValueLengthKnown() {
          return (vlen >= 0);
        }

View on GitHub (pinned to 2add963021)

Solutions

  1. Read the value exactly once per entry and keep the result in a local variable or byte[] that you pass around.
  2. Audit for hidden second reads: logging, metrics, or toString() on an entry must not touch value accessors.
  3. Advance the scanner (scanner.advance()) before touching the next entry; valueChecked resets per entry.

Example fix

// before
int n = entry.getValue(buf, 0);
java.io.DataInputStream dis = entry.getValueStream(); // IllegalStateException
// after
int n = entry.getValue(buf, 0); // single access; reuse buf/n everywhere
// if the value is needed again, keep your own copy of buf[0..n)
Defensive patterns

Strategy: validation

Validate before calling

boolean valueRead = false;
// per entry: exactly one of getValue(buf), getValue(buf, off), getValueStream()
if (!valueRead) { int n = entry.getValue(buf, 0); valueRead = true; }
// reset valueRead after scanner.advance()

Try / catch

try {
  java.io.DataInputStream dis = entry.getValueStream();
} catch (IllegalStateException e) {
  // double access bug in caller code: this entry's value was already consumed
}

Prevention

When it happens

Trigger: Calling two value accessors on one entry: getValue(buf) then getValueStream(), getValue(buf,0) twice, or logging code that peeks at the value before the main processing call. Everything works again only after scanner.advance() moves the cursor to the next entry, which resets valueChecked via checkKey().

Common situations: Debug logging added during incident response that consumes the value, helper methods that each try to read the value, or copy-paste retrieval in two layers of the call stack.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/ebfa96e9378661dc. Report an issue: GitHub.