pockethub/PocketHub · error · IOException

Unexpected response code:

Error message

Unexpected response code: 

What it means

HttpImageGetter.getDrawable() downloads an image over HTTP with OkHttp and requires a successful (2xx) response before decoding the bitmap. On any non-2xx status it throws IOException("Unexpected response code: <code>"). The code's actual HTTP status is appended at runtime.

Solutions

  1. Verify the image URL is reachable and returns 200 (curl -I).
  2. Use the placeholder/loading drawable fallback so a failed load degrades gracefully.
  3. Check auth headers are attached when loading private/authenticated images.
  4. Implement retry with backoff for 429/5xx, and cache previously loaded bitmaps.

Example fix

// before
throw new IOException("Unexpected response code: " + response.code());
// after
if (!response.isSuccessful()) {
    Log.w(TAG, "Image fetch failed: " + response.code());
    return loading.getDrawable(source);
}
Defensive patterns

Strategy: fallback

Validate before calling

// HEAD-check the URL before fetching:
// HttpURLConnection(url).requestMethod = "HEAD"; responseCode == 200

Try / catch

try {
    val d = httpImageGetter.getDrawable(source)
} catch (e: IOException) {
    loading.getDrawable(source) // placeholder fallback
}

Prevention

When it happens

Trigger: An <img> src in rendered Markdown resolves to a URL returning 404 (image deleted), 403 (hotlink protection / auth required), 401, or 5xx; redirects exhausted; rate limiting (429).

Common situations: Deleted GitHub user avatar or gist image; private image requiring auth headers; camo/proxy misconfiguration; CDN outage returning 5xx.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of pockethub/PocketHub@8228cb8f71 (2026-09-11). Data as JSON: /api/errors/9ea0f80a869dfcad. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/com/github/pockethub/android/util/HttpImageGetter.java:338

            }
        } catch (Exception e) {
            // Ignore and attempt request over regular HTTP request
        }

        try {
            String logMessage = "Loading image: " + source;
            Log.d(getClass().getSimpleName(), logMessage);
            Bugsnag.leaveBreadcrumb(logMessage);

            Request request = new Request.Builder()
                    .get()
                    .url(source)
                    .build();

            Response response = okHttpClient.newCall(request).execute();

            if (!response.isSuccessful()) {
                throw new IOException("Unexpected response code: " + response.code());
            }

            Bitmap bitmap = BitmapFactory.decodeStream(response.body().byteStream());

            if (bitmap == null) {
                return loading.getDrawable(source);
            }

            BitmapDrawable drawable = new BitmapDrawable( context.getResources(), bitmap);
            drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
            return drawable;
        } catch (IOException e) {
            Log.e(getClass().getSimpleName(), "Error loading image", e);
            Bugsnag.notify(e);
            return loading.getDrawable(source);
        }
    }

View on GitHub (pinned to 8228cb8f71)