didi/DoKit · error · UnsupportedOperationException

Mark not supported

Error message

Mark not supported

What it means

Thrown by InputStreamProxy.reset() because the proxy stream (used by DoKit to tee network/stream data to an output sink while it is consumed) explicitly does not support mark/reset — markSupported() returns false and mark() is a no-op. Calling reset() therefore fails with UnsupportedOperationException, as the proxy cannot rewind bytes already forwarded to the sink.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/stream/InputStreamProxy.java:123

        }

        return mSkipBuffer;
    }

    @Override
    public boolean markSupported() {
        // this can be implemented, but isn't needed for TeedInputStream's behavior
        return false;
    }

    @Override
    public void mark(int readlimit) {
        // noop -- mark is not supported
    }

    @Override
    public void reset() throws IOException {
        throw new UnsupportedOperationException("Mark not supported");
    }

    @Override
    public void close() throws IOException {
        super.close();
        closeOutputStreamQuietly();
    }

    private synchronized void closeOutputStreamQuietly() {
        if (!mClosed) {
            try {
                mOutputStream.close();
            } catch (IOException e) {
            } finally {
                mClosed = true;
            }
        }
    }

View on GitHub (pinned to 626827cddb)

Solutions

  1. Wrap the stream in a BufferedInputStream (or read it fully into a byte[] / ByteArrayInputStream) if you need rewind — the buffer provides mark/reset over the proxy
  2. Check markSupported() before calling reset() at every reset site
  3. Restructure to consume the stream once instead of resetting it; tee the bytes yourself if multiple passes are needed

Example fix

// before
stream.reset(); // stream is an InputStreamProxy

// after
BufferedInputStream buffered = new BufferedInputStream(stream);
buffered.mark(limit);
// ... read ...
buffered.reset(); // works: BufferedInputStream supplies mark/reset
Defensive patterns

Strategy: fallback

Validate before calling

InputStream s = (stream.markSupported()) ? stream : new BufferedInputStream(stream);
// later: if (s.markSupported()) s.reset();

Type guard

boolean canReset(InputStream in) { return in != null && in.markSupported(); }

Prevention

When it happens

Trigger: Calling reset() (directly or via a library that conditionally resets, e.g. ImageDecoder or an XML parser that checks markSupported() incorrectly) on a stream wrapped by DoKit's InputStreamProxy; some code paths call reset() unconditionally before parsing.

Common situations: Third-party parsers or decoders that reset() when markSupported() is misreported; re-reading a response stream that DoKit wrapped for capture and expecting it to rewind like a BufferedInputStream

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/0a98cf7afe0a0b0e. Report an issue: GitHub.