{"record":{"id":"2f72155230babcc6","repo":"testcontainers/testcontainers-java","slug":"http-response-code-was-s","errorCode":null,"errorMessage":"HTTP response code was: %s","messagePattern":"HTTP response code was: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/testcontainers/containers/wait/strategy/HttpWaitStrategy.java","lineNumber":295,"sourceCode":"\n                                // Choose the statusCodePredicate strategy depending on what we defined.\n                                Predicate<Integer> predicate;\n                                if (statusCodes.isEmpty() && statusCodePredicate == null) {\n                                    // We have no status code and no predicate so we expect a 200 OK response code\n                                    predicate = responseCode -> HttpURLConnection.HTTP_OK == responseCode;\n                                } else if (!statusCodes.isEmpty() && statusCodePredicate == null) {\n                                    // We use the default status predicate checker when we only have status codes\n                                    predicate = responseCode -> statusCodes.contains(responseCode);\n                                } else if (statusCodes.isEmpty()) {\n                                    // We only have a predicate\n                                    predicate = statusCodePredicate;\n                                } else {\n                                    // We have both predicate and status code\n                                    predicate =\n                                        statusCodePredicate.or(responseCode -> statusCodes.contains(responseCode));\n                                }\n                                if (!predicate.test(connection.getResponseCode())) {\n                                    throw new RuntimeException(\n                                        String.format(\"HTTP response code was: %s\", connection.getResponseCode())\n                                    );\n                                }\n\n                                if (responsePredicate != null) {\n                                    String responseBody = getResponseBody(connection);\n\n                                    log.trace(\"Get response {}\", responseBody);\n\n                                    if (!responsePredicate.test(responseBody)) {\n                                        throw new RuntimeException(\n                                            String.format(\"Response: %s did not match predicate\", responseBody)\n                                        );\n                                    }\n                                }\n                            } catch (IOException e) {\n                                throw new RuntimeException(e);\n                            }","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/core/src/main/java/org/testcontainers/containers/wait/strategy/HttpWaitStrategy.java#L277-L313","documentation":"HttpWaitStrategy polls a container's HTTP endpoint until it is ready. This RuntimeException is thrown when the server responds but the status code fails the configured statusCodePredicate (e.g. you asked for HTTP 200 but got 404/500). It usually means the endpoint is reachable but not behaving as expected yet.","triggerScenarios":"Calling HttpWaitStrategy.forStatusCode(200)/forStatusCodeMatching(predicate) (or default 200 requirement) while the container returns a different code, such as 404 for a wrong path or 503 while the app is still initializing.","commonSituations":"Wrong wait path/port configured; app returns 301/302 redirects instead of 200; endpoint returns 401 without auth headers; health endpoint briefly returns 503 during startup and the timeout window expires between polls.","solutions":["Verify the actual status code with curl against the mapped port and fix the expected path/port in the wait strategy","Allow the observed status codes via .forStatusCode(...) or .forStatusCodeMatching(...)","Ensure livenessPort/https settings match the container's real listening port and protocol","Increase .withStartupTimeout(...) if the code only transitions to 200 after longer warm-up"],"exampleFix":"// before\nnew HttpWaitStrategy().forPort(8080).forPath(\"/health\").forStatusCode(200);\n// after\nnew HttpWaitStrategy().forPort(8080).forPath(\"/actuator/health\").forStatusCode(200).forStatusCode(503).withStartupTimeout(Duration.ofSeconds(60));","handlingStrategy":"validation","validationCode":"// Verify the endpoint before waiting\nString url = \"http://\" + container.getHost() + \":\" + container.getMappedPort(8080) + \"/health\";\nHttpURLConnection c = (HttpURLConnection) new URL(url).openConnection();\nint code = c.getResponseCode();\nif (code != 200) throw new IllegalStateException(\"Endpoint returned \" + code + \", adjust forStatusCode/forPath\");","typeGuard":null,"tryCatchPattern":"try {\n    container.waitingFor(new HttpWaitStrategy().forStatusCode(200)).start();\n} catch (ContainerLaunchException e) {\n    if (e.getMessage().startsWith(\"HTTP response code was\")) {\n        // inspect container logs / adjust status predicate\n    }\n    throw e;\n}","preventionTips":["curl the mapped port and path before finalizing the wait strategy","Allow every acceptable status code explicitly via forStatusCode/forStatusCodeMatching","Keep wait path/port in sync with the application's real health endpoint","Add generous withStartupTimeout for slow-warming apps"],"tags":["http","wait-strategy","status-code","testcontainers"],"backgroundTag":"unexpected-http-status","analyzedSha":"8e549514e3f01c57d70546fbb8599d138f3903e5","analyzedAt":"2026-09-12T14:56:41.227Z","contentChangedAt":"2026-09-12T14:56:41.227Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}