didi/DoKit · error · ResponseException
responseCode + " " + connection.getResponseMessage()
Error message
responseCode + " " + connection.getResponseMessage()
What it means
UrlConnectionDownloader.load() checks the HTTP response code and throws ResponseException(responseCode + " " + responseMessage, networkPolicy, responseCode) for any status >= 300. This is Picasso's signal that the image fetch failed at the HTTP level (redirect handling exhausted, 4xx auth/missing, 5xx server error); it is caught internally by BitmapHunter and converted into the error path (error drawable / onBitmapFailed) rather than crashing the app.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/UrlConnectionDownloader.java:96
builder.append("no-cache");
}
if (!NetworkPolicy.shouldWriteToDiskCache(networkPolicy)) {
if (builder.length() > 0) {
builder.append(',');
}
builder.append("no-store");
}
headerValue = builder.toString();
}
connection.setRequestProperty("Cache-Control", headerValue);
}
int responseCode = connection.getResponseCode();
if (responseCode >= 300) {
connection.disconnect();
throw new ResponseException(responseCode + " " + connection.getResponseMessage(),
networkPolicy, responseCode);
}
long contentLength = connection.getHeaderFieldInt("Content-Length", -1);
boolean fromCache = parseResponseSourceHeader(connection.getHeaderField(RESPONSE_SOURCE));
return new Response(connection.getInputStream(), fromCache, contentLength);
}
@Override public void shutdown() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && cache != null) {
ResponseCacheIcs.close(cache);
}
}
private static void installCacheIfNeeded(Context context) {
// DCL + volatile should be safe after Java 5.
if (cache == null) {View on GitHub (pinned to 626827cddb)
Solutions
- Verify the URL in a browser or with curl -I to confirm the status code and fix the link or auth token.
- Register an error fallback via .error(R.drawable.err) or implement Target/onBitmapFailed so the UI degrades gracefully.
- For intermittent 5xx, allow retries (Picasso automatically retries failed requests up to its retry limit) and consider .networkPolicy(NetworkPolicy.NO_CACHE) to avoid caching a stale bad response path.
- If 3xx appears, ensure the server sends Location properly — HttpURLConnection follows up to 5 HTTP redirects by default; a loop yields this exception.
Example fix
// before
picasso.load(expiredSignedUrl).into(imageView); // 403, blank view
// after
picasso.load(freshUrl)
.error(R.drawable.image_fallback)
.into(imageView, new Callback() {
@Override public void onError(Exception e) {
if (e instanceof ResponseException) {
int code = ((ResponseException) e).responseCode;
tracker.logImageFailure(url, code);
}
}
@Override public void onSuccess() {}
}); Defensive patterns
Strategy: try-catch
Validate before calling
// Optional preflight — HEAD the URL to catch dead links early
// (do this off the main thread; most apps instead rely on error callbacks)
URL u = new URL(url);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("HEAD");
boolean ok = c.getResponseCode() < 300; Try / catch
// ResponseException is delivered to Callback.onError / Target.onBitmapFailed — handle there
picasso.load(url).error(R.drawable.fallback).into(imageView, new Callback.EmptyCallback() {
@Override public void onError(Exception e) {
if (e instanceof ResponseException) {
int code = ((ResponseException) e).responseCode;
log("image fetch failed HTTP " + code);
}
}
}); Prevention
- Always attach .error(...) or an error callback for remote images.
- Validate/refresh signed URLs before handing them to the image loader.
- Monitor 4xx/5xx rates per endpoint to catch expired-CDN-token incidents early.
When it happens
Trigger: Loading a URL that returns 404/410, a CDN link whose signed token expired (403), a server error (500/503), or a redirect loop (3xx not followed) — any responseCode >= 300 from the underlying HttpURLConnection.
Common situations: Expired or mis-signed image URLs; wrong Content-Type handled by a proxy; environment differences where a URL works locally but a staging/proxy returns 403; backend outage during image loads.
Related errors
- Unrecognized type of request: " + request
- Downloader must not be null.
- Stream may not be null.
- Unable to mark: <e>
- Received response with 0 content-length header.
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/ee012c3fbb0256bd.
Report an issue: GitHub.