Debugging Failed Replays¶
Replay failures are normal. Every failure is the test case telling you exactly which dynamic value, header, cookie, or URL it still doesn't know how to handle. The work of "debugging" is mostly the work of asking the right questions in the right order.
This page describes the order. The error-code-specific pages it links to are reference material for when you already know what you're looking at.
The First Principle: Fix the First Red Transaction¶
Replay errors cascade. A login transaction that fails to extract a session cookie at page two will cause every protected page after it to fail too. By the time you look at the Errors View, you might see thirty red transactions, but twenty-nine of them are downstream consequences of the first one. The first red transaction is almost always the actual root cause.
Always start there. Fix it, re-run the replay, look at the new first red transaction. Repeat until green.
Trying to fix every red transaction at once is a guaranteed way to waste an afternoon chasing symptoms.
The Most Common Failure: Unconfigured Dynamic Fields¶
If you're going to internalize one thing about debugging Load Tester, internalize this: most replay failures are an unconfigured dynamic field. A value that was set during recording (a session ID, a CSRF token, a hidden form field, an account ID embedded in a JavaScript handler, a path segment in a URL) needs to be extracted from a server response at replay time and sent back to the server on a later request. If ASM didn't catch it, the test case sends the stale recorded value, and the server rejects the request.
This shows up as 400 (the request looks malformed), 401 (the session cookie is stale), 403 (the CSRF token doesn't match), 404 (the URL contains a dead ID), or 200-with-wrong-content (the server happily returned an error page wrapped in a success status, which is why validation rules matter).
The fix is always the same shape. Find where the value first appears in a server response. Create an extractor on that response. Wire the consuming field to read from the extractor's variable. The Custom Extractors walkthrough in asm-extractors.md walks through this with a worked example.
ASM's job is to do this for you automatically for ~95% of patterns. The remaining ~5% is when you reach for a custom extractor.
The Debugging Workflow¶
When a replay fails, work through these steps in order:
Step 1: Find the First Red Transaction¶
In the Replay View or Test Case Editor, scan top to bottom for the first transaction with a red indicator. That's your target. Ignore the rest for now.
Step 2: Read the Errors View¶
The Errors View (bottom panel) lists every error with the actual message and the transaction it occurred on. The HTTP status code is useful as a category hint, but the error message is more informative. "Missing user variable: # csrf_token [1]" tells you exactly which variable didn't get extracted. "The status code of the response (403) did not match any of 200, 304" tells you the request was rejected. "Could not update variable(s)" tells you ASM placed an extractor that didn't actually match the response.
If the error mentions a missing variable, the lineage information attached to the error tells you which extractor was supposed to produce it and whether that extractor was scheduled to run before the consuming transaction. If runsBeforeConsumer is false, the extractor is on the wrong transaction (a same-transaction or later-transaction extractor can't feed a value the request needs before sending). That's a phase-ordering mistake to fix.
Step 3: Open Fields View on the Failing Transaction¶
This is the most important step and the one most users skip.
- Select the failing transaction in the editor
- Open the Fields View (bottom panel)
- Scan every field for the visual configuration state:
- Gray background: ASM configured this field. It's dynamic.
- White background: This field is using the recorded literal value. It is not dynamic.
Now ask: which fields on this transaction should be dynamic but show a white background? Those are your unconfigured dynamic fields. Session tokens, CSRF tokens, IDs, anything that varies per session. Anything you wouldn't expect to be a hardcoded literal in a real client.
This single inspection step catches the majority of replay failures. If you find a white-background field that should be dynamic, the fix is in the Custom Extractors walkthrough.
Step 4: Trace the Value Back to Its Origin¶
For any field that should be dynamic, find where the value first appears in a server response. This is what the AI assistant's find_value_origin tool does, or you can do it manually by searching the responses of previous transactions for the field's recorded value.
Once you know the origin transaction, you know where the extractor needs to live. Create it on that response, wire the consuming field to it, re-run the replay.
Step 5: Check Headers View for Header-Level Issues¶
If the Fields View doesn't reveal the problem, the failure may be in a header rather than a form field or URL parameter. Compare the recorded request headers against the replay request headers for the failing transaction. Look for:
- Cookies that should differ but match (stale session cookie)
- Authorization headers carrying stale tokens (OAuth refresh missing)
- Custom headers (
X-CSRF-Token,X-Request-ID) that the server is validating against
Most of these are correlation problems with the same shape as field-level issues: extract the value from a previous response, wire the header to read from the variable.
Step 6: Drill Into the Error-Code-Specific Page¶
If you've worked through the first five steps and the failure is still mysterious, the per-error-code pages cover the less-common causes. Pick the page that matches the error code on your first red transaction:
| Status code | Page | Common root cause |
|---|---|---|
| 401 Unauthorized | Debugging 401 | Session cookie not correlated, or no authentication configured |
| 403 Forbidden | Debugging 403 | CSRF token not correlated, permission issue, or anti-bot defense |
| 404 Not Found | Debugging 404 | Dynamic URL segment not extracted, or stale test data |
| 400 Bad Request | Debugging 400 | Malformed request body, usually a missing dynamic field |
| 405 Method Not Allowed | Debugging 405 | API method changed since recording (re-record needed) |
| 500 Internal Server Error | Debugging 500 | Server-side bug. Not a test case problem. Report it. |
| Connection refused / timeout / no route | Debugging Connection Errors | Server down, firewall, or wrong hostname |
Step 7: Use the AI Assistant¶
The AI assistant has read-access to every tool that powers steps 1–5: Errors View, Fields View, Headers View, find_value_origin, the lineage data on missing-variable errors. For complex failures, asking the AI to walk through the chain of evidence on a specific transaction is faster than doing it manually.
Useful Prompts
For a missing-variable error:
My replay fails at page 3, transaction 5 with "Missing user variable:
# session_token [1]". Trace where session_token should come from and
tell me whether the extractor is in the right place.
For a 4xx with no obvious cause:
My replay fails at page 4, transaction 2 with 403 Forbidden. Look at
the request headers and body. Compare them to the recorded request.
What's different?
For a workflow with cascade failures:
After Each Fix¶
Fix one thing. Re-run the replay. Look at the new first red transaction. Repeat.
This loop is the point of replay being a separate step before load testing. If you can make one virtual user complete the workflow without errors, scaling to a thousand virtual users is just configuration. If you can't, no amount of cloud engines and load profiles is going to save you.
When the Replay Succeeds But Something Is Still Wrong¶
A replay with zero errors isn't proof the test case is correct. The server can return 200 OK with the wrong content: an error page wrapped in success status, a logged-out view that looks normal, a CAPTCHA challenge, a session-expired notice. The transaction-level red/green indicator only catches HTTP-level failures.
Validation Rules catch this class of silent failure. Add at least one Content Contains rule on every authenticated page that asserts the user is actually authenticated (their name, an account-specific link, anything only a logged-in user would see). Configure once, runs on every replay and every load test from then on.
Next Steps¶
- If replay succeeded: Proceed to Configuring a Load Test
- If replay is still failing: Drill into the per-error-code page for your specific status code
- For complex configuration questions: See Custom Extractors, Authentication, or The Replay View for live-replay inspection
Related Topics: