apache/hadoop · error · IOException

Reset called without a previous mark

Error message

Reset called without a previous mark

What it means

The special case in ValueIterator.reset(): when clearMark() is called during reset-mode iteration, clearMarkFlag stays set until the iteration finishes; the next reset() consumes the flag, clears the backup store's mark, and throws IOException('Reset called without a previous mark'). One rewind is granted per mark — once the mark is cleared, no live mark remains to reset to.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/task/ReduceContextImpl.java:287

          WritableUtils.getVIntSize(currentKeyLength) +
          WritableUtils.getVIntSize(currentValueLength);
        DataOutputStream out = backupStore.getOutputStream(requestedSize);
        writeFirstKeyValueBytes(out);
        backupStore.updateCounters(requestedSize);
      } else {
        backupStore.mark();
      }
    }

    @Override
    public void reset() throws IOException {
      // We reached the end of an iteration and user calls a 
      // reset, but a clearMark was called before, just throw
      // an exception
      if (clearMarkFlag) {
        clearMarkFlag = false;
        backupStore.clearMark();
        throw new IOException("Reset called without a previous mark");
      }
      
      if (!isMarked) {
        throw new IOException("Reset called without a previous mark");
      }
      inReset = true;
      backupStore.reset();
    }

    @Override
    public void clearMark() throws IOException {
      if (getBackupStore() == null) {
        return;
      }
      if (inReset) {
        clearMarkFlag = true;
        backupStore.clearMark();
      } else {

View on GitHub (pinned to 2add963021)

Solutions

  1. Call mark() again before every reset() you intend to use
  2. Treat clearMark() as terminal for that group — only clear when no further rewind is needed
  3. Encapsulate the mark/reset dance in one helper that tracks state explicitly
Defensive patterns

Strategy: validation

Validate before calling

class Rewinder {
  private final ValueIterator<KEYIN, VALUEIN> it;
  private boolean liveMark = false;
  void rewind() throws IOException {
    if (!liveMark) { it.mark(); liveMark = true; }
    it.reset();
  }
  void doneRewinding() throws IOException { it.clearMark(); liveMark = false; }
}

Try / catch

try {
  it.reset();
} catch (IOException e) { // 'Reset called without a previous mark'
  it.mark();
  it.reset();
}

Prevention

When it happens

Trigger: Sequence mark(); reset(); partial iteration; clearMark(); then reset() again without re-marking. The second reset lands here.

Common situations: Two-pass reducer logic that rewinds per key group and clears marks to free backup-store space, then rewinds once more on a corner case; hand-rolled mark/reset state machines losing track of whether the mark survives.

Related errors


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