square/okhttp · error · IOException
Unexpected code
Error message
Unexpected code
What it means
Recipe-level guard on the FIRST of two identical GETs that demonstrate HTTP caching. The client is built with a 10 MiB disk Cache; on the first request the cache is cold so the response must come from the network. If that network response is not 2xx, java.io.IOException("Unexpected code " + response1) is thrown before the cache is populated.
Source
Thrown at samples/guide/src/main/java/okhttp3/recipes/CacheResponse.java:44
private final OkHttpClient client;
public CacheResponse(File cacheDirectory) throws Exception {
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(cacheDirectory, cacheSize);
client = new OkHttpClient.Builder()
.cache(cache)
.build();
}
public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
String response1Body;
try (Response response1 = client.newCall(request).execute()) {
if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1);
response1Body = response1.body().string();
System.out.println("Response 1 response: " + response1);
System.out.println("Response 1 cache response: " + response1.cacheResponse());
System.out.println("Response 1 network response: " + response1.networkResponse());
}
String response2Body;
try (Response response2 = client.newCall(request).execute()) {
if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2);
response2Body = response2.body().string();
System.out.println("Response 2 response: " + response2);
System.out.println("Response 2 cache response: " + response2.cacheResponse());
System.out.println("Response 2 network response: " + response2.networkResponse());
}
System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body));View on GitHub (pinned to 4fc0831380)
Solutions
- Check response1.code(), response1.cacheResponse(), and response1.networkResponse() to determine whether it was a network round-trip and what the origin said.
- Verify the cache directory exists and is writable; check Cache.directory() and Cache.size() after the call.
- Confirm the URL is reachable with curl; the cache only helps once the origin is healthy.
- Use https:// to avoid redirect-related status codes.
Example fix
// before
try (Response response1 = client.newCall(request).execute()) {
if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1);
...
}
// after
try (Response response1 = client.newCall(request).execute()) {
if (!response1.isSuccessful()) {
throw new IOException("Warm-up failed: HTTP " + response1.code()
+ " network=" + response1.networkResponse()
+ " cache=" + response1.cacheResponse());
}
...
} Defensive patterns
Strategy: validation
Validate before calling
// Verify cache directory is writable before constructing the client
File dir = cacheDirectory;
if (!dir.exists() && !dir.mkdirs()) throw new IOException("Cannot create cache dir: " + dir);
if (!dir.canWrite()) throw new IOException("Cache dir not writable: " + dir);
Cache cache = new Cache(dir, 10 * 1024 * 1024);
OkHttpClient client = new OkHttpClient.Builder().cache(cache).build(); Try / catch
try (Response response1 = client.newCall(request).execute()) {
if (!response1.isSuccessful()) {
throw new HttpException(response1.code(),
"network=" + response1.networkResponse() + ", cache=" + response1.cacheResponse());
}
// warm the cache
} Prevention
- Ensure the cache directory exists and is writable.
- Confirm the origin is reachable before expecting a cache warm-up.
- Use https:// to avoid redirect-related status codes.
- Log networkResponse() vs cacheResponse() to understand which path served the response.
When it happens
Trigger: First client.newCall(request).execute() for http://publicobject.com/helloworld.txt with caching enabled. Fires on any non-2xx from the origin: host down (would actually be transport IOException, not this), 404, 503, or a non-cacheable error. Because this is the cache-warming request, failure here means the second request (error [4]) cannot be a cache hit either.
Common situations: Cache directory not writable (separate failure: the cache silently no-ops or throws earlier); origin server returning 5xx; running offline and expecting the cache to serve stale content (OkHttp does not serve stale-on-error unless a separate fallback is configured); the demo domain returning a redirect to https.
Related errors
AI-assisted analysis of square/okhttp@4fc0831380 (2026-08-04).
Data as JSON: /data/errors/b446fa9fd3bcbf8d.json.
Report an issue: GitHub.