{"record":{"id":"20f4b568d7eb3e54","repo":"karatelabs/karate","slug":"proceed-needs-a-target-url-or-host-header-in-request","errorCode":null,"errorMessage":"proceed() needs a target URL or Host header in request","messagePattern":"proceed\\(\\) needs a target URL or Host header in request","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/core/KarateJs.java","lineNumber":1008,"sourceCode":"     * // Forward using Host header from request\n     * var response = karate.proceed();\n     * </pre>\n     */\n    private JavaInvokable proceed() {\n        return args -> {\n            if (mockHandler == null) {\n                throw new RuntimeException(\"proceed() can only be called within a mock scenario\");\n            }\n            HttpRequest currentRequest = mockHandler.getCurrentRequest();\n\n            String targetUrl;\n            if (args.length > 0 && args[0] != null) {\n                targetUrl = args[0].toString();\n            } else {\n                // Use Host header from request\n                String host = currentRequest.getHeader(\"Host\");\n                if (host == null) {\n                    throw new RuntimeException(\"proceed() needs a target URL or Host header in request\");\n                }\n                targetUrl = \"http://\" + host;\n            }\n\n            // Build request manually to avoid header conflicts\n            HttpRequestBuilder builder = new HttpRequestBuilder(client);\n            builder.url(targetUrl);\n            builder.path(currentRequest.getPath());\n            builder.method(currentRequest.getMethod());\n\n            // Copy headers except those that will be auto-set\n            if (currentRequest.getHeaders() != null) {\n                currentRequest.getHeaders().forEach((name, values) -> {\n                    String lowerName = name.toLowerCase();\n                    // Skip headers that are auto-managed\n                    if (!lowerName.equals(\"content-length\") && !lowerName.equals(\"host\")\n                            && !lowerName.equals(\"transfer-encoding\")) {\n                        builder.header(name, values);","sourceCodeStart":990,"sourceCodeEnd":1026,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/KarateJs.java#L990-L1026","documentation":"When karate.proceed() is called without an explicit target URL, Karate falls back to building the target from the incoming request's Host header (\"http://\" + host). This error is thrown when there is no argument AND the intercepted request carries no Host header, so Karate has no way to determine where to forward the request.","triggerScenarios":"Calling karate.proceed() with no arguments from a mock scenario whose incoming request lacks a Host header — e.g. an HTTP/1.0-style client, a raw socket request built without Host, or a request whose Host header was stripped/renamed before reaching the mock.","commonSituations":"Testing with a minimal HTTP client or curl variant that omits Host; a proxy/load balancer in front of the mock rewriting or dropping the Host header; forwarding non-HTTP-protocol traffic at the mock; passing a custom header name (e.g. X-Forwarded-Host) and expecting proceed() to use it.","solutions":["Pass the target URL explicitly: var response = karate.proceed('http://backend:8080')","Ensure the client sends a standard Host header with its request to the mock","If a proxy strips Host, configure it to preserve Host, or use an X-Forwarded-Host value by passing that URL explicitly to proceed()","For test clients, force HTTP/1.1 so Host is mandatory, e.g. curl --http1.1"],"exampleFix":"// before\n* def response = karate.proceed() // fails if request has no Host header\n\n// after\n* def response = karate.proceed('http://backend:8080')","handlingStrategy":"validation","validationCode":"// Before relying on Host-header fallback in a mock scenario, pass the URL explicitly when unsure:\nvar target = 'http://backend:8080';\nvar response = karate.proceed(target);","typeGuard":null,"tryCatchPattern":"try {\n  var response = karate.proceed(); // Host-header mode\n} catch (e) {\n  if (('' + e).indexOf('needs a target URL or Host header') !== -1) {\n    var response = karate.proceed('http://backend:8080');\n  } else { throw e; }\n}","preventionTips":["Always pass the explicit target URL to proceed() in tests you control","Verify client requests include a Host header (mandatory in HTTP/1.1)","Check any proxy in front of the mock preserves the Host header","Note proceed() only reads the plain 'Host' header — X-Forwarded-Host is not used automatically"],"tags":["javascript","mock-server","http-headers","karate"],"backgroundTag":"missing-required-argument","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}