jhy/jsoup · error · UncheckedIOException

Mark invalid

Error message

Mark invalid

What it means

Internal state error in CharacterReader.rewindToMark: it fires when bufMark is still the sentinel -1, i.e. mark() was never called (or unmark()/rewindToMark already consumed the mark) before a rewind was attempted. It is a marker of a reader-protocol violation by calling code that rewinds without an outstanding mark.

Solutions

  1. Call mark() before rewinding; every rewindToMark() must be paired with a preceding mark().
  2. Do not rewind twice on the same mark — rewindToMark() clears the mark via unmark(); re-mark if you need to rewind again.
  3. If wrapping CharacterReader, preserve the mark protocol: mark before any speculative consume-then-rewind sequence, since bufferUp() may invalidate assumptions.
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at src/main/java/org/jsoup/parser/CharacterReader.java:139 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of jhy/jsoup@9851ac5d9c (2026-09-08). Data as JSON: /api/errors/0903227d11c74987. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/org/jsoup/parser/CharacterReader.java:139

        scanBufferForNewlines(); // if enabled, we index newline positions for line number tracking
    }

    void mark() {
        // make sure there is enough look ahead capacity
        if (bufLength - bufPos < RewindLimit)
            fillPoint = 0;

        bufferUp();
        bufMark = bufPos;
    }

    void unmark() {
        bufMark = -1;
    }

    void rewindToMark() {
        if (bufMark == -1)
            throw new UncheckedIOException(new IOException("Mark invalid"));

        bufPos = bufMark;
        unmark();
    }

    /**
     * Gets the position currently read to in the content. Starts at 0.
     * @return current position
     */
    public int pos() {
        // consuming EOF advances to a virtual position so it can be unconsumed; don't expose that beyond the input
        return consumed + Math.min(bufPos, bufLength);
    }

    /**
     Enables or disables line number tracking. By default, will be <b>off</b>.Tracking line numbers improves the
     legibility of parser error messages, for example. Tracking should be enabled before any content is read to be of
     use.

View on GitHub (pinned to 9851ac5d9c)