{"record":{"id":"a69f9973cf4d3782","repo":"square/okhttp","slug":"unexpected-code-a69f99","errorCode":null,"errorMessage":"Unexpected code ","messagePattern":"Unexpected code ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"samples/guide/src/main/java/okhttp3/recipes/PreemptiveAuth.java","lineNumber":41,"sourceCode":"import okhttp3.Response;\n\npublic final class PreemptiveAuth {\n  private final OkHttpClient client;\n\n  public PreemptiveAuth() {\n    client = new OkHttpClient.Builder()\n        .addInterceptor(\n            new BasicAuthInterceptor(\"publicobject.com\", \"jesse\", \"password1\"))\n        .build();\n  }\n\n  public void run() throws Exception {\n    Request request = new Request.Builder()\n        .url(\"https://publicobject.com/secrets/hellosecret.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 PreemptiveAuth().run();\n  }\n\n  static final class BasicAuthInterceptor implements Interceptor {\n    private final String credentials;\n    private final String host;\n\n    BasicAuthInterceptor(String host, String username, String password) {\n      this.credentials = Credentials.basic(username, password);\n      this.host = host;\n    }\n","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/square/okhttp/blob/91a8b34c6f44bd28c421364f8edadc9f324dddd9/samples/guide/src/main/java/okhttp3/recipes/PreemptiveAuth.java#L23-L59","documentation":"Thrown in the PreemptiveAuth recipe: `if (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response)`. A BasicAuthInterceptor unconditionally adds an Authorization header for requests to the configured host BEFORE the server challenges. If the credentials are wrong or the resource is gone, the server returns non-2xx and this throws. Because auth is preemptive, there is no 401->retry flow here.","triggerScenarios":"GET https://publicobject.com/secrets/hellosecret.txt with a preemptive Basic header returns 401/403 (wrong credentials), 404 (secret file removed), or 5xx. The interceptor matches only requests whose host equals 'publicobject.com', so a redirect to a different host would drop the header and likely yield 401.","commonSituations":"Using literal sample credentials 'jesse'/'password1' against a live server; the protected resource was removed; the server expects a scheme other than Basic; the host filter is too narrow/wide.","solutions":["Replace the sample username/password with real credentials.","Confirm the secret path still exists (404 is not an auth failure).","Log response.code() to distinguish 401/403 (auth) from 404 (missing).","Make the host match in the interceptor match your actual target host(s)."],"exampleFix":"// before\nif (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response);\n\n// after\nif (response.code() == 401 || response.code() == 403) {\n  throw new IOException(\"Preemptive auth rejected (HTTP \" + response.code() + \")\");\n}\nif (!response.isSuccessful()) throw new IOException(\"HTTP \" + response.code());","handlingStrategy":"try-catch","validationCode":"// Confirm the secret path exists; verify credentials before relying on preemptive auth.\nif (!validCredentials) throw new IllegalStateException(\"configure real credentials\");\n...\nif (response.code() == 401 || response.code() == 403) { /* auth failure */ return; }","typeGuard":"static boolean preemptiveAuthAccepted(Response r) { return r.code() != 401 && r.code() != 403; }","tryCatchPattern":"try {\n  // call\n} catch (IOException e) {\n  // includes 'Unexpected code' (HTTP status; often 401/403 for bad creds, 404 for missing path)\n}","preventionTips":["Do not hardcode sample credentials; load real ones from config/secrets.","Make the interceptor's host match your actual target host(s).","Distinguish 401/403 (auth) from 404 (missing resource).","Confirm the secret path still exists."],"tags":["okhttp","http-status","authentication","preemptive-auth","basic-auth","java"],"backgroundTag":null,"analyzedSha":"91a8b34c6f44bd28c421364f8edadc9f324dddd9","analyzedAt":"2026-08-10T18:39:54.316Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}