didi/DoKit · error · IllegalStateException
Cannot set request property after connection is made
Error message
Cannot set request property after connection is made
What it means
setRequestProperty() is only legal before the connection is established; the wrapper's 'connected' flag flips to true inside buildCall() (triggered by connect, output/input streams, response code), after which setRequestProperty throws IllegalStateException("Cannot set request property after connection is made"). This preserves the standard HttpURLConnection contract.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/urlconnection/ObsoleteUrlFactory.java:685
if (proxy != null) return true;
Proxy clientProxy = client.proxy();
return clientProxy != null && clientProxy.type() != Proxy.Type.DIRECT;
}
@Override
public String getResponseMessage() throws IOException {
return getResponse(true).message();
}
@Override
public int getResponseCode() throws IOException {
return getResponse(true).code();
}
@Override
public void setRequestProperty(String field, String newValue) {
if (connected) {
throw new IllegalStateException("Cannot set request property after connection is made");
}
if (field == null) {
throw new NullPointerException("field == null");
}
if (newValue == null) {
return;
}
requestHeaders.set(field, newValue);
}
@Override
public void setIfModifiedSince(long newValue) {
super.setIfModifiedSince(newValue);
if (ifModifiedSince != 0) {
requestHeaders.set("If-Modified-Since", format(new Date(ifModifiedSince)));
} else {
requestHeaders.removeAll("If-Modified-Since");View on GitHub (pinned to 626827cddb)
Solutions
- Set all request properties before the first connect-triggering call.
- In retry loops, create a new connection and re-apply all headers from a saved map.
- Review code paths where interceptors/callbacks mutate the connection after writing starts.
Example fix
// before
conn.connect();
conn.setRequestProperty("Authorization", token); // ISE
// after
conn.setRequestProperty("Authorization", token);
conn.connect(); Defensive patterns
Strategy: validation
Validate before calling
// apply every header from a map before any connect-triggering call: for (Map.Entry<String,String> e : headers.entrySet()) conn.setRequestProperty(e.getKey(), e.getValue());
Try / catch
try { conn.setRequestProperty(k, v); } catch (IllegalStateException ignored) { /* already connected: reopen connection instead */ } Prevention
- Enforce 'headers first, then connect, then body' ordering in all HTTP helper code.
- For retries, rebuild a fresh connection and re-apply headers from your own map.
When it happens
Trigger: Calling setRequestProperty() (or setRequestProperty-based helpers like setIfModifiedSince after connect) once connect()/getOutputStream()/getInputStream()/getResponseCode() has run.
Common situations: Setting an Authorization header lazily inside a retry loop; interleaving header setup with streaming-body writes; auth interceptors that patch headers late.
Related errors
- Cannot access request header fields after connection is set
- cannot write request body after response has been read
- Cannot add request property after connection is made
- Already connected
- This protocol does not support input
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/0d64c39aded181e3.
Report an issue: GitHub.