skip to content

In a JMeter run, why can a Regular Expression Extractor's variable still hold the previous iteration's value?

level: seniorimportance: must knowfreq 57%

answer

  1. Nothing clears the variable between iterations
  2. The default is written before matching, conditionally
  3. Blank field, unticked box, no write
  4. Group variables vanish, the main one stays

basics

~20 s

Because JMeter only writes the Default Value when that field is non-empty or Use empty default value is ticked. With both left alone, a failed match writes nothing and the variable keeps whatever the last successful match put there.

solid answer

~50 s

A JMeter variable belongs to its thread and survives the loop, so nothing clears it between iterations. The **Regular Expression Extractor** writes the **Default Value** into the reference variable *before* it runs the pattern, but only under one condition: the Default Value must be non-empty, or the **Use empty default value** checkbox must be ticked. Leave the field blank with the box unticked and a failed match writes nothing at all, so the variable silently keeps the token captured on some earlier iteration. The thread then re-posts a stale CSRF token; the server rejects it, but the extractor has no complaint to make. The fix is in the element itself — set a distinctive Default Value such as `CSRF_NOT_FOUND` so a miss becomes visible downstream, or tick **Use empty default value** when the capture is genuinely optional and an empty string is the right stand-in.

go deeper

for a junior

Recall that the Default Value field is what the reference variable holds when the pattern does not match, and that leaving it blank means no fallback is written.

for a middle

Explain that JMeter writes the default before matching and only when the field is non-empty or Use empty default value is ticked, so a blank field leaves the old value in place.

for a senior

Diagnose a repeated captured value across iterations of one thread: check whether the group variables disappeared, then set a distinctive Default Value so the next miss announces itself.

for a principal

Make an unmistakable Default Value a review requirement for every extractor in the suite, and decide where an optional capture may legitimately fall back to an empty string.

## Why the variable survives at all JMeter variables are per-thread and live for as long as the thread does. Looping does not reset them, and no extractor removes the reference variable on a miss. Everything below follows from that single fact: if the element does not write, the old value stays. ## When the Default Value is actually written The extractor writes the Default Value into the reference variable at the *start* of processing, before the pattern runs, and it does so only when one of these holds: - the **Default Value** field is non-empty; or - the **Use empty default value** checkbox is ticked, in which case the variable is set to the empty string. If neither holds, the element makes no write to the reference variable at all before matching. A successful match then overwrites the default; an unsuccessful one leaves whatever was written, which is either the default you configured or the value from the last successful pass. The component reference is candid about this being a design choice rather than an oversight: leaving the default blank is what you want when several elements set the same variable and a non-matching one should not clobber it. That is a deliberate technique, not the common case, and it is worth being able to say so in an interview. ## The signature of a stale capture The CSRF case is the canonical one. The plan requests a form page, lifts the hidden `_csrf` input into `csrfToken`, and posts it. On the iteration where the form page comes back as a redirect, an error page or a cached body without the hidden input, the extractor misses. `${csrfToken}` still resolves — to the previous iteration's token — so the POST is well-formed and the server rejects it on a different code path than a malformed one. Signs that this is what you are looking at: - the same captured value appearing across many iterations of one thread when it should change every time; - `refName_g0` and `refName_g1` **absent** while `refName` is present. On a miss with a non-negative Match No., JMeter removes the group variables and `refName_g` but leaves the reference variable alone, so that asymmetry is the fingerprint; - the failure clustering on iterations that follow some other anomaly, rather than being spread randomly. ## Making a miss visible 1. **Give every extractor a distinctive Default Value.** `CSRF_NOT_FOUND` in a request body is unmissable in a result log; an empty string or a stale token is not. This is the single highest-value habit on this element. 2. **Tick Use empty default value only when the capture is optional.** It makes `${var}` resolve to an empty string rather than to the literal `${var}`, which is the right behaviour for a genuinely optional field and the wrong one for a mandatory token. 3. **Check the group variables when debugging.** Their disappearance tells you the extractor ran and found nothing, as opposed to never running. 4. **Prefer a value that cannot be mistaken for real data.** A default of `0` or an empty string can travel a long way through a plan before anyone notices. ## The Boundary Extractor behaves the same way Everything above applies unchanged to the **Boundary Extractor**: it writes the Default Value before matching under the same condition, and a miss with no default configured leaves the previous value in place just as readily. Two differences are worth carrying: - it writes no group variables at all, so the missing-`_g0` fingerprint above is not available there — with a negative Match No. you are left checking `refName_matchNr`; - a blank **Name of created variable** raises an IllegalArgumentException rather than failing quietly, which is the one place this element is stricter than its pattern-based sibling. ## The asymmetry worth remembering On a miss with a non-negative Match No. the extractor removes `refName_g0`, `refName_g1` and `refName_g`, but never removes `refName` itself — it only overwrites it when a default is configured. Knowing which of the two happens is exactly the difference between guessing at a stale value and diagnosing one.

  • What does the Use empty default value checkbox change when the Default Value field is already blank?
    It makes JMeter set the variable to an empty string instead of not writing it at all. Downstream `${var}` then resolves to nothing rather than to the literal text `${var}`, which is the right behaviour when the captured value is genuinely optional.
  • When is leaving the Default Value blank deliberately the right choice?
    When several extractors write the same variable and a non-matching one should leave the earlier capture untouched. The component reference calls this out explicitly, and recommends removing the default only once debugging is complete.
  • How do you tell a missed extraction apart from an extractor that never ran?
    Look at the group variables. A miss with a non-negative Match No. removes `refName_g0`, `refName_g1` and `refName_g` while leaving the reference variable; an extractor that never ran leaves all of them exactly as the previous pass left them.

saying these in an interview costs you the question

  • Assumes JMeter resets variables at the start of each iteration
  • Says a failed extraction always leaves the variable empty
  • Thinks the Default Value is only for the GUI tester panels
  • Cannot explain why a blank Default Value is ever the right choice
  • Blames the sampler rather than checking the extractor's own fields