karatelabs/karate · error · RuntimeException
proceed() needs a target URL or Host header in request
Error message
proceed() needs a target URL or Host header in request
What it means
HttpRequest.proceed(targetUrl) re-sends/replays the request against a new target. If targetUrl is null it falls back to building http://<Host header>. When neither a target URL nor a Host header exists there is nowhere to forward the request, so it throws.
Solutions
- Pass an explicit target: request.proceed("https://other-host.example")
- Set a Host header before proceeding: request.header("Host", "other-host.example") then proceed(null)
- If replaying on the same host, pass the original base URL rather than null
- When intercepting/proxying, copy the inbound Host header onto the HttpRequest before calling proceed
Example fix
// before
response.getRequest().proceed(null); // throws when Host header absent
// after
response.getRequest().proceed("http://backend.internal:8080"); Defensive patterns
Strategy: try-catch
Validate before calling
var req = response.getRequest();
if (targetUrl == null && req.getHeader("Host") == null) {
throw new Error('proceed() requires a target URL; request has no Host header');
} Try / catch
try {
response.getRequest().proceed(targetUrl);
} catch (RuntimeException e) {
if (e.getMessage().contains("proceed() needs a target URL")) {
// fall back to the original absolute URL
response.getRequest().proceed(originalBaseUrl);
} else { throw e; }
} Prevention
- Always pass an explicit absolute target URL to proceed()
- When proxying, copy the inbound Host header onto the rebuilt request
- Never rely on the Host fallback for programmatically-built requests
When it happens
Trigger: Calling request.proceed(null) (or proceed() via a binding that omits the arg) on a request that has no 'Host' header set — e.g. a request built programmatically with only a path, or a request whose Host header was stripped by an intermediary or by the caller before proceeding.
Common situations: Implementing proxy/redirect-following logic where the upstream response/request lost its Host header; testing forward() style flows with hand-built HttpRequest objects; environment changes where requests previously came with Host headers but now come from a builder that never set one.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- incomplete http request, 'url' not set
- Failed to fetch content from URL
- waitForHttp() needs a URL argument
- HTTP endpoint not available
- http method expression evaluated to null:
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/c3a29b25ec4888f3.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/http/HttpRequest.java:709
return args -> {
if (args.length > 0) {
return getFiles(args[0] + "");
} else {
throw new RuntimeException("missing argument for files()");
}
};
}
/**
* Forward this request to a target URL and return the response.
* Mirrors {@code karate.proceed()} so JS-file mocks can implement proxy behavior.
* If {@code targetUrl} is null, uses the {@code Host} header on this request.
*/
public HttpResponse proceed(String targetUrl) {
if (targetUrl == null) {
String host = getHeader("Host");
if (host == null) {
throw new RuntimeException("proceed() needs a target URL or Host header in request");
}
targetUrl = "http://" + host;
}
HttpClient client = httpClient != null ? httpClient : new DefaultHttpClientFactory().create();
HttpRequestBuilder builder = new HttpRequestBuilder(client);
builder.url(targetUrl);
builder.path(path);
builder.method(method);
if (headers != null) {
headers.forEach((name, values) -> {
String lowerName = name.toLowerCase();
if (!lowerName.equals("content-length") && !lowerName.equals("host")
&& !lowerName.equals("transfer-encoding")) {
builder.header(name, values);
}
});
}
Object converted = getBodyConverted();View on GitHub (pinned to a22eb90246)