didi/DoKit · error · IllegalStateException
Already in chunked mode
Error message
Already in chunked mode
What it means
setFixedLengthStreamingMode(long) refuses to run when chunked streaming mode is already enabled (chunkLength > 0), throwing IllegalStateException("Already in chunked mode"). A request body can use exactly one transfer strategy: fixed-length or chunked, not both.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/urlconnection/ObsoleteUrlFactory.java:738
}
@Override
public void setRequestMethod(String method) throws ProtocolException {
if (!METHODS.contains(method)) {
throw new ProtocolException("Expected one of " + METHODS + " but was " + method);
}
this.method = method;
}
@Override
public void setFixedLengthStreamingMode(int contentLength) {
setFixedLengthStreamingMode((long) contentLength);
}
@Override
public void setFixedLengthStreamingMode(long contentLength) {
if (super.connected) throw new IllegalStateException("Already connected");
if (chunkLength > 0) throw new IllegalStateException("Already in chunked mode");
if (contentLength < 0) throw new IllegalArgumentException("contentLength < 0");
this.fixedContentLength = contentLength;
super.fixedContentLength = (int) Math.min(contentLength, Integer.MAX_VALUE);
}
@Override
public void onFailure(Call call, IOException e) {
synchronized (lock) {
this.callFailure = (e instanceof UnexpectedException) ? e.getCause() : e;
lock.notifyAll();
}
}
@Override
public void onResponse(Call call, Response response) {
synchronized (lock) {
this.response = response;
this.handshake = response.handshake();View on GitHub (pinned to 626827cddb)
Solutions
- Pick one streaming mode per connection; remove the conflicting setChunkedStreamingMode call.
- If both code paths must coexist, guard with a flag so only the first mode call wins.
- Prefer fixed-length when the body size is known; use chunked only when it is not.
Example fix
// before conn.setChunkedStreamingMode(0); conn.setFixedLengthStreamingMode(body.length); // ISE // after conn.setFixedLengthStreamingMode(body.length); // only one mode
Defensive patterns
Strategy: validation
Validate before calling
boolean streamingModeSet = false;
void setStreaming(HttpURLConnection c, long len) {
if (streamingModeSet) return; // first mode wins
if (len >= 0) c.setFixedLengthStreamingMode(len); else c.setChunkedStreamingMode(0);
streamingModeSet = true;
} Prevention
- Choose one transfer mode per connection and centralize that choice in one method.
- Audit wrappers/libraries that default to chunked before your code sets fixed length.
When it happens
Trigger: Calling setChunkedStreamingMode(...) and then setFixedLengthStreamingMode(...) on the same connection — commonly when one layer (e.g. a cookie/auth wrapper or library default) enables chunked while app code sets fixed length.
Common situations: Framework code defaulting to chunked uploads while the app sets an exact content length; merging two upload implementations that each pick a streaming mode.
Related errors
- Already connected
- Cannot access request header fields after connection is set
- This protocol does not support input
- method does not support a request body: ${method}
- cannot write request body after response has been read
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/2bfa641180536e8f.
Report an issue: GitHub.