PRACTICAL GUIDE / Selenium Grid trace ID propagation test reports
Correlate Selenium Grid failures without guessing by timestamp
Carry a stable test and session identity into reports, then use Selenium Grid logs to find the exact trace IDs behind a distributed failure.
In this guide6 sections
What you will learn
- Trace IDs and session IDs solve different joins
- Publish the correlation keys before the test can fail
- Find the right command traces from a failed report
- Prove whether Grid or the application failed
A remote test times out, and its report says only that an element never appeared. The Grid has thousands of log events from parallel sessions at the same minute. Matching by timestamp gives you a plausible failure, but not necessarily the failure that belonged to this test.
Trace IDs and session IDs solve different joins
Selenium Grid 4 instruments server requests with OpenTelemetry. A trace follows one request as it crosses Grid components, and every span in that trace shares a trace ID. Structured events can include the trace ID, span ID, handler class, HTTP details, exceptions, and attributes such as session.id.
The important word is request. A browser session sends many WebDriver commands: create session, navigate, find element, click, execute script, take screenshot, and delete session. Those commands do not form one guaranteed Grid trace. A single test can therefore be associated with several trace IDs.
The Selenium client does not expose a public method that returns the Grid's current OpenTelemetry trace ID. RemoteWebDriver.getSessionId() returns something different and more useful for report correlation: the WebDriver session ID. Grid includes that value in many command paths and event attributes, so it joins all the command-level traces for one browser session.
You still need a key that joins the session back to the test framework. Selenium Grid accepts metadata capabilities whose names start with se:. se:name gives the session a human-readable test name in the Grid UI. A second value such as se:reportId can carry a unique result identifier. The Grid documentation explicitly allows se: metadata and makes it available through session capabilities and GraphQL.
This produces a defensible chain:
test result ID -> se:reportId -> WebDriver session ID -> Grid event -> trace ID -> spansCalling a client-generated UUID a "Grid trace ID" breaks that chain. It may be a useful correlation ID, but it is not the trace ID emitted by Grid's OpenTelemetry instrumentation.
Publish the correlation keys before the test can fail
The following JUnit 5 test runs against a local Grid, adds report metadata to the session request, and publishes the actual Selenium session ID to the test result. It uses Selenium's public Java APIs and the project's standard web-form fixture.
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.net.URI;
import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.TestReporter;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
class GridCorrelationTest {
@Test
void submitsWebForm(TestInfo testInfo, TestReporter testReporter) throws Exception {
String reportId = "junit-" + UUID.randomUUID();
ChromeOptions options = new ChromeOptions();
options.setCapability("se:name", testInfo.getDisplayName());
options.setCapability("se:reportId", reportId);
RemoteWebDriver driver = new RemoteWebDriver(
URI.create("http://localhost:4444").toURL(),
options);
String sessionId = driver.getSessionId().toString();
testReporter.publishEntry(Map.of(
"gridReportId", reportId,
"seleniumSessionId", sessionId));
try {
driver.get("https://www.selenium.dev/selenium/web/web-form.html");
driver.findElement(By.name("my-text")).sendKeys("correlation check");
driver.findElement(By.cssSelector("button")).click();
assertEquals("Received!", driver.findElement(By.id("message")).getText());
} finally {
driver.quit();
}
}
}Publish the entry immediately after session creation. If the Node disappears during navigation, the report already owns the session ID. Publishing it only in teardown is risky because a failed setup, a killed worker, or an invalid session can prevent teardown from completing.
The example uses a random report ID so parallel executions with the same display name remain distinct. In a real suite, prefer the stable identifier assigned by the report system if it is available before the session starts. Include the CI run and attempt when a test can be retried. The display name is for people; the unique ID is for joins.
Avoid putting secrets, customer names, or full parameter payloads in se: capabilities. Capabilities can appear in the Grid UI, GraphQL responses, and logs. A short opaque identifier is enough.
Find the right command traces from a failed report
Start Grid with tracing enabled and enough log detail to emit structured events. This command assumes the current server jar has been saved as selenium-server.jar:
java -jar selenium-server.jar standalone \
--tracing true \
--structured-logs true \
--log-level FINE \
--log grid.logTracing is enabled by default in Selenium Grid, but spelling it out makes the diagnostic setup reviewable. FINE is important because normal trace events are not all printed at the default INFO level. Error events can appear at WARN, yet relying only on errors removes the successful spans immediately before the failure.
Copy seleniumSessionId from the failed test result and search the Grid log:
rg 'paste-session-id-here' grid.logTo list the distinct trace IDs on matching lines, use the actual session value in the first search:
rg 'paste-session-id-here' grid.log \
| rg -o '"traceId"\s*:\s*"[0-9a-f]+"' \
| sort -uSeveral IDs are normal. Open the trace for the command nearest the test's failing action, then follow its spans across the Router, Distributor, Session Map, and Node components involved in that request. Check handler names, duration, HTTP status, and exception attributes. The last successful command for the same session is often more informative than an unrelated warning emitted a second later.
Preserve command order in the incident note. Record the last successful WebDriver operation, the first failed operation, and the delete-session result. A cleanup trace can fail because the Node has already disappeared, but that later error should not replace the earlier command that caused the test to lose progress. Conversely, a healthy delete-session trace proves cleanup worked; it does not prove the preceding click or script command was healthy.
Trace IDs copied by hand are easy to transpose. Have the enrichment step generate a direct backend link from the exact ID returned by the log query, and store the plain ID beside the link. The link improves triage, while the plain value remains useful if the backend hostname or URL format changes.
If an OpenTelemetry backend receives Grid spans, query it by the session.id attribute when that attribute is available, then link the chosen trace from the test report. A backend link is lighter and safer than attaching the entire Grid log. Its cost is coupling the report to the backend's access controls and retention window.
GraphQL provides another useful check while the session is active. Querying the session by ID can show capabilities, Node URI, start time, and slot details. It does not replace distributed traces, and finished sessions may no longer be queryable. Capture needed session metadata during execution rather than expecting Grid to act as a permanent report database.
Prove whether Grid or the application failed
A WebDriver timeout in the test report does not by itself blame Grid. The browser may have loaded a slow application, the locator may be wrong, or a Grid component may have delayed the command. Correlated evidence lets you separate those cases.
An application synchronization failure usually has a normal command path through Grid. Spans complete without infrastructure exceptions, the Node continues serving commands, and the browser screenshot or page source shows the wrong product state. Fix the wait, locator, test data, or application behavior.
A Node or network failure looks different. The relevant trace may contain a long gap, connection exception, unavailable Node, or failed forwarding call. Other commands for the same session may stop at the same boundary. Preserve the component name and first exception rather than replacing them with the test framework's later timeout.
A queue or capacity problem is most visible around new-session creation, before a browser session ID may exist. That is why the se:reportId metadata and CI attempt ID matter. Search the new-session request evidence by that identifier, and inspect Grid queue and Distributor telemetry. A session-ID-only strategy cannot correlate a session that was never created.
Retries create another ownership trap. A framework may run the same test name twice with two different WebDriver sessions. Publish a separate session ID for every attempt and never overwrite the first one with the retry. A green retry does not make the original Grid path irrelevant, especially when the purpose of the evidence is to distinguish flaky infrastructure from flaky application behavior.
When several browser projects execute the same scenario, include browser name and platform with the attempt record. Those values help select the right session, but they are filters rather than primary keys. Two Chrome sessions on the same Node still require unique result and session IDs.
Timestamp-only matching fails under concurrency. Clock skew, buffering, retries, and dozens of simultaneous commands can put several plausible events in the same window. Time is useful for narrowing a search after identity is known, not for establishing ownership.
Pay the observability cost deliberately
FINE structured logging creates volume. On a busy Grid, writing every event to local disk can add I/O pressure and rotate logs quickly. An external tracing backend adds ingestion, storage, and operational cost. Start with failure lanes or a representative environment, measure the volume, and set retention based on the team's investigation window.
Detailed telemetry can expose URLs, browser capabilities, stack traces, and application context. Restrict access and redact before copying excerpts into broadly visible reports. Keep the report entry small: test ID, session ID, selected trace link, and perhaps the failing component.
Custom client instrumentation can propagate a trace context through systems you own, but modifying the WebDriver transport solely to inject headers is a maintenance commitment. Client bindings, proxies, and Grid routing can change. Prefer Selenium's session ID and metadata surfaces unless end-to-end organizational tracing already justifies that integration.
The correlation code also needs ownership. Put session/report publication in a driver fixture or test extension so every remote test gets it once. The trade-off is framework coupling: the extension must understand retries, parallel execution, and result attachment. Scattered print statements are cheaper initially and unreliable when the suite grows.
Skip trace propagation when a smaller record answers the question
A local browser test that never touches Grid does not need Grid trace correlation. Driver logs, the exception, and a screenshot are usually enough.
Do not attach every span to every successful test. Most results need only the identifiers required to retrieve telemetry later. Export full evidence on failure or during a bounded performance investigation.
Avoid building a tracing pipeline to mask weak test naming. If ten parameterized cases publish the same display name, fix the result identity first. Observability cannot reliably join records that were ambiguous at their source.
Finally, do not use a Grid trace to decide whether the product assertion passed. A perfectly healthy Router and Node can deliver the wrong page state quickly. Grid telemetry explains the automation infrastructure's path; the test still owns the business result.
// FIELD DISPATCH
Get the QA Field Notes
Weekly QA battles, AI testing guides, and interview drills. Free on Substack.
// LIVE COURSE / THE TESTING ACADEMY
Playwright Automation Mastery
Go beyond Selenium. Master Playwright with JS/TS in 90 days.
From the instructor behind this guide.
Playwright jobs are growing 8x faster than Selenium. 90 days / 75+ live hrs / Tue-Thu-Sat 7 AM IST.
PRIMARY REFERENCES
Verify the details at the source
QABattle guides are practical explanations. Product behavior, standards, and APIs can change, so use these primary references for the canonical details.
- 01Official selenium.dev reference
selenium.dev
Primary documentation selected and verified for the claims in this guide.
- 02Official selenium.dev reference
selenium.dev
Primary documentation selected and verified for the claims in this guide.
- 03Official selenium.dev reference
selenium.dev
Primary documentation selected and verified for the claims in this guide.
- 04Official selenium.dev reference
selenium.dev
Primary documentation selected and verified for the claims in this guide.
FAQ / QUICK ANSWERS
Questions testers ask
Can a Selenium test read the Grid trace ID from WebDriver?
Not through the standard WebDriver client API. The test can reliably read its session ID, while Grid structured logs or an OpenTelemetry backend expose the trace IDs created for server requests.
Why does one Selenium session have several trace IDs?
Each WebDriver command is a separate request to Grid and can start its own distributed trace. The session ID is the common value that joins navigation, element, script, and cleanup requests from the same browser session.
What identifier should a test report always include for Grid failures?
Use the Selenium session ID as the minimum correlation key, and add a unique report or test-run ID as `se:` metadata when creating the session. Together they connect the test framework, Grid capabilities, and server telemetry.
How do I get the session ID in Java?
Keep the `RemoteWebDriver` instance and call `getSessionId()` after session creation succeeds. Publish the string before risky test steps so a later browser crash cannot erase the only link to Grid evidence.
Are FINE-level Selenium Grid logs safe to attach to reports?
Detailed logs may contain URLs, capabilities, exception text, and other environment data. Restrict access, redact sensitive fields, and attach a trace link or filtered excerpt instead of copying the full Grid log into every report.
RELATED GUIDES
Continue the learning route
GUIDE 01
Selenium Grid Trace Correlation with Test IDs
Master Selenium grid trace correlation with practical examples, architecture decisions, failure analysis, CI guidance, metrics, and scenario-led interview answers.
GUIDE 02
Test Selenium Grid External Session Map Failover
Learn Selenium Grid external session map failover testing with working code, failure cases, debugging steps, and CI evidence for reliable QA automation.
GUIDE 03
Selenium Grid Kubernetes Interview Questions
Selenium grid Kubernetes interview questions: practical design, implementation, debugging, CI, metrics, and interview guidance for QA, SDET, and automation engineers.
GUIDE 04
Selenium Grid Multi-Region Architecture
A practical guide to Selenium grid multi region architecture, covering design, implementation, debugging, scale, measurable release gates, and senior interview scenarios.
GUIDE 05
Debug Selenium Grid Event Bus Connectivity
Master debug Selenium grid event bus with practical examples, architecture decisions, failure analysis, CI guidance, metrics, and scenario-led interview answers.