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
- 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
- Check markSupported() before calling reset() at every reset site
- 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
- Always check markSupported() before mark()/reset()
- Wrap DoKit-proxied streams in BufferedInputStream or read them fully into memory if re-reading is required
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
- Unable to mark: <e>
- Cannot reset
- closed
- Failed to decode stream.
- leakTraceAsFakeException() can only be called when leakFound
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/0a98cf7afe0a0b0e.
Report an issue: GitHub.