Gatling baseUrl works locally but fails in production containers: is an explicit scheme required?
0 reputation · 29 Sept 2021, 02:10 UTC
0 reputation · 29 Sept 2021, 02:10 UTC
We configure the HTTP protocol in our Gatling simulations with .baseUrl(...), and the same simulation runs successfully on developer machines but fails when executed in our production container and CI agent environments. The simulations target Gatling 3.x with the Java DSL.
The value being passed resembles a bare host and port, such as localhost:8080, without an http:// or https:// scheme. Our understanding is that Gatling's underlying HTTP client may treat a scheme-less value as a relative reference rather than an absolute URI, and that resolution could then depend on the JVM working directory, which differs between local runs (project root) and containers (e.g., /opt/gatling or /app). We have not found documentation stating that Gatling validates or auto-corrects baseUrl into an absolute URI.
1. Does Gatling require baseUrl to be an absolute URI with an explicit scheme, and is the working-directory-dependent resolution the documented explanation for environment-specific failures?
2. Does a trailing slash on the base URL change how request paths are resolved, and should it be mandated in our configuration?
3. Is externalizing baseUrl via environment variables or gatling.conf the intended mechanism for per-environment overrides without editing simulation code?
35775 reputation · 29 Sept 2021, 03:40 UTC
Gatling's http.baseUrl(...) (Gatling 3.x, Java DSL) expects an absolute URI including a scheme, such as http://localhost:8080. Gatling does not validate, normalize, or auto-correct the value; it is passed to the underlying HTTP client, which needs the scheme to select a protocol handler and open a connection. A value like localhost:8080 is not a usable absolute URI, so request construction or connection fails.
Confirmed by behavior: the missing scheme is the defect. Fix that first.
Likely, not confirmed: the working-directory theory is probably a misconception. Relative-URI resolution against the JVM working directory is not how Gatling's HTTP client builds request URLs. The more plausible reason it "works locally" is an environmental difference — for example, a local run actually receiving a different value (an IDE run configuration, a Maven/Gradle default, or a shell variable) than the container. Verify by logging the resolved value at startup in both environments.
Be deliberate about it. Gatling concatenates the base URL with the path passed to http(...). A base of http://host:8080/api combined with request path /users can drop the api segment depending on how paths are joined. The safe convention: end the base URL with a trailing slash and start request paths without a leading slash ("users"). Mandate one convention in your team rather than mixing both.
Yes — externalizing is the intended pattern. The common approach is a system property with a local default:
HttpProtocolBuilder httpProtocol = http
.baseUrl(System.getProperty("baseUrl", "http://localhost:8080/"));Then pass it in CI or the container:
JAVA_OPTS="-DbaseUrl=https://api.internal.example/" gatling.shEnvironment variables via System.getenv("BASE_URL") or a Typesafe Config entry work equally well; the key point is that simulation code stays identical across environments.
MalformedURLException or connection error points at the URI, while 404 responses point at path joining (the trailing-slash convention).Note: this reflects well-established Gatling 3.x behavior; confirm against your exact Gatling version's documentation, as DSL details can change between minor releases.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.