{"record":{"id":"5fd4a849cb433425","repo":"square/okhttp","slug":"unexpected-code-5fd4a8","errorCode":null,"errorMessage":"Unexpected code ","messagePattern":"Unexpected code ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"samples/guide/src/main/java/okhttp3/recipes/CheckHandshake.java","lineNumber":55,"sourceCode":"        if (denylist.contains(pin)) {\n          throw new IOException(\"Denylisted peer certificate: \" + pin);\n        }\n      }\n      return chain.proceed(chain.request());\n    }\n  };\n\n  private final OkHttpClient client = new OkHttpClient.Builder()\n      .addNetworkInterceptor(CHECK_HANDSHAKE_INTERCEPTOR)\n      .build();\n\n  public void run() throws Exception {\n    Request request = new Request.Builder()\n        .url(\"https://publicobject.com/helloworld.txt\")\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 CheckHandshake().run();\n  }\n}\n","sourceCodeStart":37,"sourceCodeEnd":65,"githubUrl":"https://github.com/square/okhttp/blob/91a8b34c6f44bd28c421364f8edadc9f324dddd9/samples/guide/src/main/java/okhttp3/recipes/CheckHandshake.java#L37-L65","documentation":"Thrown in the CheckHandshake recipe AFTER the denylist interceptor already ran: `if (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response)`. The handshake interceptor only rejects denylisted certs; for everything else it calls chain.proceed(). This line then fires if the server returned a non-2xx HTTP status on a handshake that was allowed through.","triggerScenarios":"The handshake interceptor did not block the cert (pin not in denylist), chain.proceed() completed, but https://publicobject.com/helloworld.txt returned 404/403/5xx.","commonSituations":"Sample host removed helloworld.txt; server-side error; confusing a denylist rejection (which throws earlier at line 38) with this HTTP-status throw.","solutions":["Distinguish the two throws in this file: line 38 is the security denylist, line 55 is plain HTTP status.","Inspect response.code() to identify the real HTTP problem.","Confirm the resource path still exists.","Branch on the code instead of throwing to keep the demo's diagnostics usable."],"exampleFix":"// before\nif (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response);\n\n// after\nif (!response.isSuccessful()) {\n  throw new IOException(\"HTTP \" + response.code() + \" (handshake passed denylist)\");\n}","handlingStrategy":"validation","validationCode":"// Distinguish the two throws in this file by code/message.\ntry (Response r = client.newCall(request).execute()) {\n  if (!r.isSuccessful()) { /* HTTP status only; denylist would have thrown earlier */ return; }\n} catch (IOException e) {\n  if (e.getMessage().contains(\"Denylisted\")) { /* security event */ }\n}","typeGuard":"static boolean handshakePassedDenylist(IOException e) { return e.getMessage() == null || !e.getMessage().startsWith(\"Denylisted\"); }","tryCatchPattern":"try {\n  // call\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Denylisted peer certificate\")) {\n    // line 38 security event\n  } else if (e.getMessage() != null && e.getMessage().startsWith(\"Unexpected code\")) {\n    // line 55 HTTP status\n  }\n}","preventionTips":["Tell apart line 38 (denylist) from line 55 (HTTP status) by the exception message.","Inspect response.code() to identify the HTTP problem.","Keep the denylist current so legitimate requests are not blocked.","Branch on code instead of throwing for clearer HTTP diagnostics."],"tags":["okhttp","http-status","interceptor","java"],"backgroundTag":null,"analyzedSha":"91a8b34c6f44bd28c421364f8edadc9f324dddd9","analyzedAt":"2026-08-10T18:39:54.316Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}