How to Modify HTTP Request Headers With Selenium WebDriver in Java
Add or replace request headers in Selenium Java using Chrome DevTools Protocol, and learn what WebDriver BiDi supports and where Java API support differs.
To add or replace HTTP request headers in Selenium WebDriver with Java, use Selenium’s Chrome DevTools Protocol (CDP) support with Chrome or Edge. CDP’s Network.setExtraHTTPHeaders applies extra headers to browser network requests. WebDriver BiDi defines a standards-based network.setExtraHeaders command, but the documented Selenium Java Network module does not list a direct helper for it. Check your exact Selenium release before relying on BiDi from Java.
This guide shows the Chromium CDP approach, how to validate the server received the header, and how the BiDi option differs. For standard WebDriver Classic there is no general command to rewrite arbitrary browser network requests.
1. Choose the protocol and confirm your setup
| Approach | Use it when | Check before implementing |
|---|---|---|
| CDP | You automate Chrome or Edge and need to set extra request headers. | Pin and verify the Selenium and browser combination. CDP is browser-specific and its API can depend on browser versions. |
| WebDriver BiDi | You want the standards-based cross-browser direction and your browser and Selenium Java release support the required command. | The W3C protocol defines network.setExtraHeaders, but the documented Selenium Java Network module does not list a direct method with that name. |
| WebDriver Classic | You need ordinary browser automation without network-level header rewriting. | Classic WebDriver has no general command for changing arbitrary browser request headers. |
Selenium describes CDP support as temporary while BiDi implementation continues. CDP is practical for Chromium automation today, but keep the browser and Selenium versions compatible. The Selenium BiDi guide enables the WebSocket connection with options.setCapability("webSocketUrl", true); that capability alone does not establish that a particular Java release exposes the extra-header command.
2. Add headers with Selenium Java and CDP
The example below uses Selenium’s generated Chrome DevTools API. The package for the DevTools version can vary with Selenium and browser protocol versions. Match the vNNN package to a version available in your Selenium dependency; do not assume the sample package compiles unchanged with every release.
Maven dependency
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>YOUR_PINNED_SELENIUM_VERSION</version>
</dependency>
Use a concrete Selenium version managed by your project. The following Java example illustrates the CDP flow; replace vNNN with the generated Chrome DevTools package present in that version.
import java.util.Map;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.vNNN.network.Network;
import org.openqa.selenium.devtools.vNNN.network.model.Headers;
public class HeaderExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
try {
DevTools devTools = ((ChromeDriver) driver).getDevTools();
devTools.createSession();
devTools.send(Network.enable(
java.util.Optional.empty(),
java.util.Optional.empty(),
java.util.Optional.empty()
));
Map headerValues = Map.of(
"X-Test-Run", "selenium-java",
"Authorization", "Bearer " + System.getenv("TEST_BEARER_TOKEN")
);
devTools.send(Network.setExtraHTTPHeaders(new Headers(headerValues)));
driver.get("https://your-controlled-test-endpoint.example/echo-headers");
// Inspect the controlled endpoint's response or logs to confirm receipt.
} finally {
driver.quit();
}
}
}
The endpoint hostname above is a placeholder: replace it with an endpoint you control that reports or records received request headers. Keep secrets in environment or test configuration, and do not log token values. The Selenium CDP Network documentation provides the Java Network.setExtraHTTPHeaders route; consult the API docs for your selected generated package when adapting imports and signatures.
What this code does
- Creates a Chrome session and a DevTools session.
- Enables the Network domain.
- Sets extra header values before navigation.
- Navigates to a controlled endpoint so you can verify the outgoing request.
Set the headers before driver.get so they are in place for the navigation. The command sets extra headers for network requests in the CDP session; it is not a response-header modifier and is not a per-request callback for custom conditional logic.
3. Header behavior and important edge cases
Existing headers and replacement
BiDi specifies that extra headers extend or overwrite existing request headers. If an extra header has the same name as an existing one, its value replaces the existing value; it is not appended. Treat header names case-insensitively, as HTTP does, and avoid setting multiple differently cased keys that represent the same field.
Scope and request types
Verify the specific traffic that matters to your test: the initial document navigation, redirects, subresources, and requests initiated by scripts may have different behavior depending on protocol implementation and browser. Do not infer that a header reached every request merely because the page loaded. Use a controlled endpoint or server-side request logs to inspect it.
Authentication and cookies
An Authorization header is not the same as browser-managed authentication or cookie state. Use the mechanism expected by the application under test. Do not put credentials in a URL. Be especially careful when setting authorization globally: redirects or third-party subresources can make the scope of credentials broader than intended.
Workers and browsing contexts in BiDi
The BiDi specification notes ambiguity for workers associated with multiple navigables. If using BiDi extra headers in a browser with workers or multiple contexts, validate actual request behavior for that setup rather than assuming a single page-wide scope.
Conditional per-request changes
network.setExtraHeaders sets extra headers; it does not mean arbitrary callback logic for each request. Per-request interception is a separate network feature. Selenium’s Java BiDi Network API lists interception-related methods, but check the release API for the exact operations it provides.
4. WebDriver BiDi: what Java support means
The W3C WebDriver BiDi specification defines network.setExtraHeaders, with headers and optional browsing or user context scope. Its semantics say an existing value is overwritten. Selenium’s Java BiDi guide uses a WebSocket connection, typically enabled with:
ChromeOptions options = new ChromeOptions();
options.setCapability("webSocketUrl", true);
WebDriver driver = new ChromeDriver(options);
This enables the BiDi connection where supported; it does not by itself set headers. In the documented Selenium Java API, org.openqa.selenium.bidi.module.Network is marked beta and lists methods such as interception and continuation, but does not list a direct setExtraHeaders helper. Avoid presenting a raw protocol command as a stable Java Selenium method unless your exact release documents a supported way to issue it.
When selecting BiDi, verify all three layers: the browser implements the command, the Selenium Java version can issue it, and the scope/semantics fit your request. For a tested Chromium-only use case where the CDP helper is available, the CDP example above is the direct Java route.
5. Validate the request instead of assuming
- Use an endpoint in a controlled test environment that echoes or records incoming headers.
- Set a harmless marker such as
X-Test-Runalongside any required test credential. - Navigate after setting headers and inspect the endpoint response or server logs.
- Check redirects and relevant subresources separately if the test depends on them.
- Remove secrets from assertion output, screenshots, logs, and failure reports.
A successful page load does not prove the custom header was sent. A server may ignore a header, and browser tools may apply it to a different set of requests than your test expects.
6. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
Java cannot resolve org.openqa.selenium.devtools.vNNN. |
The placeholder protocol package is not present in your Selenium artifact. | Inspect the generated DevTools packages shipped with your pinned Selenium version and use the matching package/API. |
Network.setExtraHTTPHeaders or its constructor signature does not compile. |
Generated CDP APIs differ across versions. | Use the Network and Headers classes documented for the exact Selenium release; do not mix imports from different protocol versions. |
| Browser fails to create a DevTools session. | Selenium, browser, and CDP protocol versions may not align, or the selected driver does not expose the expected API. | Use a compatible pinned combination and follow that release’s Selenium CDP documentation. |
| The endpoint does not receive the header. | Headers may have been set after navigation, the wrong endpoint/request was inspected, or the server/test setup is not reporting the request received. | Set headers before navigation and verify against a controlled endpoint or server logs. |
| The original value is missing. | The extra header uses the same name and replaces the existing value. | Choose a distinct test header or provide the intended replacement value. |
| BiDi setup connects but no Java method sets extra headers. | The protocol command exists, but the Java wrapper in that release may not expose it. | Check the exact Selenium Java API. Use a documented supported route; do not assume WebSocket enablement creates a helper method. |
| A header appears on navigation but not on a worker request, or vice versa. | Request scope and worker/navigable relationships can affect behavior. | Reproduce with the relevant worker and context structure and verify server-side receipt for each request class. |
| Authorization works on one origin but causes unexpected behavior after redirects. | Credentials are being applied more broadly than the test intended or the destination has different authentication requirements. | Use a controlled target, avoid cross-origin credentials, and limit test scope to the intended environment. |
7. Performance, reliability, and cost
Setting a small header map is generally a configuration step rather than a reason to add a separate proxy hop, but this dossier provides no benchmark figures. Measure the full browser workflow if latency matters. Reuse the browser session when appropriate, and avoid repeatedly creating DevTools sessions or changing headers when one stable configuration covers the test.
Reliability depends on protocol and version compatibility. CDP is browser-specific and tied to browser protocol versions; pin browser and Selenium versions in automation environments and validate upgrades. BiDi is the standards-based direction, but verify command availability in both the browser and the Selenium Java release. For test stability, confirm headers at the receiving server and keep credentials in secure test configuration.
Selenium and CDP have no per-header charge described in the cited documentation. Your operational costs are the browser infrastructure and any services or endpoints your test uses; no sourced numeric cost or performance claim applies here.
8. Or skip the browser setup
If your actual goal is to capture a page rather than test browser request behavior, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. It accepts a URL in one GET request and returns PNG, JPEG, WebP, or PDF. It is not a replacement for a Selenium test that must assert application request headers.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie banners are accepted and removed before the shot, along with known newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed. An MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.
9. FAQ
Can I modify headers with ordinary Selenium WebDriver commands?
Not arbitrary browser network headers through a general WebDriver Classic command. Use a browser protocol feature such as CDP, or a supported BiDi operation.
Does BiDi append a second value when a header already exists?
The specification says the extra value overwrites the existing value for the same header name.
Can I use this exact CDP code with Firefox?
No. The shown generated API is Chrome DevTools Protocol-specific. Choose a protocol and Java API supported by your target browser.
Does setting an extra header guarantee it reaches every request from a page?
No. Verify the request types and contexts your test relies on at a controlled receiving endpoint.


