skip to content

Why does night two of `jmeter -n -t plan.jmx -l r.jtl -e -o report` fail before any sampling?

level: seniorimportance: should knowfreq 46%

answer

  1. The failure happens before the plan is parsed
  2. Something left over from the previous run
  3. The dashboard's destination has a precondition
  4. Either clear it or point somewhere new

basics

~20 s

The -o folder must not exist or must be empty. JMeter checks it before loading the plan, so the first night's dashboard files make the second night abort with 'Cannot write to ... as folder is not empty' and exit status 1.

solid answer

~40 s

JMeter resolves `-o` at the very top of the CLI branch, before the `.jmx` is read. `JOrphanUtils.canSafelyWriteToFolder` rejects a path that is an existing plain file, a directory containing any entry, or a missing directory whose parent is unwritable. Night one fills `report/` with `index.html` and friends, so night two throws `IllegalArgumentException: Cannot write to '<abs path>' as folder is not empty`. That lands in JMeter's catch-all handler, which prints `An error occurred: ...` and calls `System.exit(1)`. Because the check precedes the run, nothing was sampled and no JTL rows were written. The two fixes are `-f`, which makes the same check delete and recreate the folder, or a distinct output folder per run — JMeter will not date-stamp it for you.

code

text · 10 lines
text
$ jmeter -n -t plan.jmx -l r.jtl -e -o /opt/nightly/report
An error occurred: Cannot write to '/opt/nightly/report' as folder is not empty
$ echo $?
1

$ jmeter -n -t plan.jmx -e
Incorrect Usage:Option -e requires -l option
... full option list ...
$ echo $?
0

go deeper

for a junior

Remember the precondition: the folder named by -o must be absent or empty before the run.

for a middle

Explain that the check runs before the plan is loaded, and name the two ways out: -f, or a different folder each run.

for a senior

Diagnose from the artefacts. An empty JTL plus this message means nothing ran, and knowing which failures exit 1 and which exit 0 tells you what your monitoring will actually catch.

for a principal

Decide whether nightly dashboards are overwritten or accumulated, and make that decision part of the standard invocation rather than something each engineer discovers.

## The check that runs before the plan is even loaded `-o` (`--reportoutputfolder`) is handled by `extractAndSetReportOutputFolder`, which JMeter calls at the very top of the CLI branch — before the `.jmx` is read, before the tree is compiled, before a single thread starts. It does two things: 1. Calls `JOrphanUtils.canSafelyWriteToFolder` on the path. 2. If that passes, sets the JMeter property `jmeter.reportgenerator.outputdir` to the folder's absolute path. `canSafelyWriteToFolder` refuses in three situations, each with its own message: | Situation | Message | |---|---| | Path exists and is a plain file | `Cannot write to '<abs>' as it is an existing file` | | Path is a directory that lists any entry | `Cannot write to '<abs>' as folder is not empty` | | Path does not exist and the parent is not writable | `Cannot write to '<abs>' as folder does not exist and parent folder is not writable` | Night one creates `report/` and fills it with `index.html`, `content/`, `sbadmin2-1.0.7/` and the rest. Night two hits case two, and the run never begins. ## What the failure looks like The refusal is an `IllegalArgumentException`. It is not the "incorrect usage" family, so it falls into JMeter's catch-all handler: ``` An error occurred: Cannot write to '/opt/nightly/report' as folder is not empty ``` and that handler calls `System.exit(1)`. So this particular mistake does surface as a non-zero exit status — unlike an unresolvable `-t`, which prints a usage message and ends with `0`. Note the ordering carefully: because the folder check runs first, **no** samples were taken and **no** JTL row was written. An empty or stale results file after a red night is the expected outcome here, not a second bug. ## Two ways to make night two work - **Add `-f`.** The same `deleteResultFile` flag that clears results files is handed to the folder check; with it, a non-empty folder is deleted recursively and recreated instead of rejected. One stable report path, last night's report gone. - **Give each night its own folder.** `-o /opt/nightly/report-20260909` never collides, so the history stays. JMeter will not build the dated name for you: only the `-j` run-log argument is date-pattern expanded, so the string has to be assembled before the process starts. ## The other three rules these flags carry - **`-e` requires `-l`.** `-e` (`--reportatendofloadtests`) takes no argument and only asks for the dashboard to be built when the load test ends. If no `-l` was given there is no results file to build it from, so JMeter throws `Option -e requires -l option`. That one *is* an incorrect-usage error: it prints `Incorrect Usage:` plus the option list and ends with `0`. - **`-o` alone does nothing but check.** Without `-e` (or `-g`) no report generator is created, yet the folder check still runs. So `-o` on its own can fail a run that was never going to produce a report. - **`-g` is the report-only mode and excludes the run flags.** `-g <results file>` is declared incompatible with `-n`, `-r`, `-R` and `-l`; combining them is rejected by the argument parser with an `Incompatible options` error and the usage list, before anything starts. Use `-g` to build a dashboard from a JTL you already have; what that dashboard contains is a separate subject. ## What the exit status is and is not telling you Everything above is about whether the *invocation* was legal and whether JMeter could write where you pointed it. It says nothing about the results: - A run whose responses were all errors still ends with status `0`. - If the dashboard build itself fails after a successful test, JMeter prints `Error generating the report: ...` on standard error and the process still ends normally. JMeter's exit status does not encode a latency or error-rate threshold; deciding a run's verdict is a separate concern from invoking it.

  • Would adding -f have prevented it?
    Yes. The deleteResultFile flag -f sets is passed into the same folder check, which then deletes the folder recursively and recreates it rather than refusing. It also deletes the results files every ResultCollector in the tree names, so the whole run starts from clean artefacts.
  • What if you pass -o but forget -e?
    The folder check still runs and can still abort the run, but no report generator is created, so no dashboard is produced. -o on its own is a precondition with no payoff. Adding -e without -l is the mirror mistake and fails with `Option -e requires -l option`.
  • Can you rebuild the dashboard later from the same JTL?
    Yes, with `-g <results file> -o <folder>`. That is report-only mode; the parser rejects it in combination with -n, -r, -R or -l. The same empty-folder rule applies to its -o, so a repeat build needs -f or a new folder.

saying these in an interview costs you the question

  • Thinks JMeter overwrites the report folder by default
  • Says the run sampled first and only failed at report time
  • Believes -e alone generates a dashboard without -l
  • Assumes -o without -e is harmless
  • Expects the exit status to reflect whether requests succeeded