{"id":"ebc3523e61c72ff2","repo":"square/okhttp","slug":"unexpected-code-ebc352","errorCode":null,"errorMessage":"Unexpected code ","messagePattern":"Unexpected code ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"samples/guide/src/main/java/okhttp3/recipes/RequestBodyCompression.java","lineNumber":59,"sourceCode":"  private final OkHttpClient client = new OkHttpClient.Builder()\n      .addInterceptor(new GzipRequestInterceptor())\n      .build();\n  private final Moshi moshi = new Moshi.Builder().build();\n  private final JsonAdapter<Map<String, String>> mapJsonAdapter = moshi.adapter(\n      Types.newParameterizedType(Map.class, String.class, String.class));\n\n  public void run() throws Exception {\n    Map<String, String> requestBody = new LinkedHashMap<>();\n    requestBody.put(\"longUrl\", \"https://publicobject.com/2014/12/04/html-formatting-javadocs/\");\n    RequestBody jsonRequestBody = RequestBody.create(\n        mapJsonAdapter.toJson(requestBody), MEDIA_TYPE_JSON);\n    Request request = new Request.Builder()\n        .url(\"https://www.googleapis.com/urlshortener/v1/url?key=\" + GOOGLE_API_KEY)\n        .post(jsonRequestBody)\n        .build();\n\n    try (Response response = client.newCall(request).execute()) {\n      if (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response);\n\n      System.out.println(response.body().string());\n    }\n  }\n\n  public static void main(String... args) throws Exception {\n    new RequestBodyCompression().run();\n  }\n\n  /** This interceptor compresses the HTTP request body. Many webservers can't handle this! */\n  static class GzipRequestInterceptor implements Interceptor {\n    @Override public Response intercept(Chain chain) throws IOException {\n      Request originalRequest = chain.request();\n      if (originalRequest.body() == null || originalRequest.header(\"Content-Encoding\") != null) {\n        return chain.proceed(originalRequest);\n      }\n\n      Request compressedRequest = originalRequest.newBuilder()","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/square/okhttp/blob/4fc083138014aba3d0078f5c26d1ce84815fa984/samples/guide/src/main/java/okhttp3/recipes/RequestBodyCompression.java#L41-L77","documentation":"OkHttp's Response.isSuccessful() returns true only when the HTTP status code is in [200, 300). The recipe at RequestBodyCompression.java:59 wraps any non-2xx response in an IOException with the literal message 'Unexpected code ' concatenated with the Response's toString(). This is a sample-recipe convention, not a dedicated OkHttp exception type, so the stack trace is the only signal of which upstream API actually rejected the call.","triggerScenarios":"Posting JSON to https://www.googleapis.com/urlshortener/v1/url?key=<key> after Google retired the URL Shortener API (March 2018) — server returns 404/410/403. Also triggered when the GzipRequestInterceptor (RequestBodyCompression.java:70-82) sets Content-Encoding: gzip and Google's front end refuses the gzipped request body with a 400/415. A revoked/invalid GOOGLE_API_KEY (hardcoded at line 38) yields 403 Forbidden.","commonSituations":"Running the bundled OkHttp samples verbatim against a now-deprecated Google endpoint; copying the recipe's hardcoded API key into production; enabling client-side request-body gzip against a server that does not advertise gzip request-encoding support; switching from http to a vhost that returns a non-2xx error page.","solutions":["Replace the Google URL Shortener URL with a live endpoint (e.g. Firebase Dynamic Links) or a local mock server that returns 200, since the URL Shortener API is fully shut down.","Inspect the failing Response before throwing — log response.code(), response.headers(), and response.body().string() — to identify 401/403/404/415 precisely.","If keeping GzipRequestInterceptor, confirm the upstream server supports Content-Encoding: gzip on requests, otherwise drop the interceptor or gate it on a per-host condition.","Obtain a fresh Google API key from https://console.developers.google.com/project and enable the relevant API for it; never ship the sample key 'AIzaSyAx2WZYe0My0My0i-uGurpvraYJxO7XNbwiGs'."],"exampleFix":"// before\ntry (Response response = client.newCall(request).execute()) {\n  if (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response);\n  System.out.println(response.body().string());\n}\n\n// after\ntry (Response response = client.newCall(request).execute()) {\n  if (!response.isSuccessful()) {\n    String body = response.peekBody(2048).string();\n    throw new IOException(\"Unexpected code \" + response.code()\n        + \" for \" + request.url() + \": \" + body);\n  }\n  System.out.println(response.body().string());\n}","handlingStrategy":"try-catch","validationCode":"// Validate the endpoint is alive and the key is set before the call\nString apiKey = System.getenv(\"GOOGLE_API_KEY\");\nif (apiKey == null || apiKey.isBlank()) {\n  throw new IllegalStateException(\"GOOGLE_API_KEY env var not set\");\n}\n// Prefer a live endpoint; the URL Shortener API is shut down.\nif (request.url().toString().contains(\"urlshortener/v1/url\")) {\n  throw new IllegalStateException(\"URL Shortener API is deprecated; switch endpoint\");\n}","typeGuard":null,"tryCatchPattern":"try (Response response = client.newCall(request).execute()) {\n  if (!response.isSuccessful()) {\n    throw new IOException(\"HTTP \" + response.code() + \" \"\n        + response.peekBody(2048).string());\n  }\n  handle(response.body().string());\n} catch (IOException e) {\n  // distinguish network failure (no response) from non-2xx (has code)\n  throw new RuntimeException(\"URL shortener call failed: \" + e.getMessage(), e);\n}","preventionTips":["Never copy sample API keys into production; read them from env/secrets.","If using GzipRequestInterceptor, confirm the server accepts gzip request bodies (very few do).","Pin to a live endpoint — deprecated Google APIs will always return non-2xx.","Always include response.code() and a body snippet in thrown IOExceptions for diagnosis."],"tags":["okhttp","java","http-status","deprecated-api","gzip","google-api"],"analyzedSha":"4fc083138014aba3d0078f5c26d1ce84815fa984","analyzedAt":"2026-08-04T19:09:04.639Z","schemaVersion":2}