Free tools Windows power users keep installed
One-click scans. No signup required.
With Java’s built-in HttpClient, add request-specific headers on HttpRequest.Builder before calling build(). Use header(name, value) to add a value, setHeader(name, value) to replace values already set for that name, or headers(...) to supply several name/value pairs at once. Some headers—such as Content-Length—are managed or restricted by the client and cannot safely be set this way.
Send headers on an HttpRequest
The Java standard HTTP client has been available since Java 11. Build an HttpClient, create an HttpRequest for the target URI, add the headers to its builder, then send the completed request. This example uses documented Java SE API methods; it illustrates the request pattern and is not a report of a tested network call.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HeaderExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(
URI.create("https://example.com/api"))
.header("Accept", "application/json")
.header("X-Request-Id", "abc123")
.GET()
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println(response.body());
}
}
Save it as HeaderExample.java and run it with a JDK that includes the Java HTTP client API. Replace the example URI with an endpoint you are authorized to call. send is synchronous: it waits for the response and can throw checked exceptions, which is why this small example declares throws Exception. In application code, handle the relevant exceptions at the boundary where you can decide whether to retry, report an error, or stop.
Headers belong to the request builder, not to a global client setting in this pattern. That makes request-specific values such as an API-specific accept type or request ID explicit on the request that uses them. The builder methods return the builder, so calls can be chained before build().
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchChoose the right header method
| Method | What it does | Use it when |
|---|---|---|
header(name, value) |
Adds a value for the named header. Repeated calls can add more values. | You intend to add a header value, including when building a request progressively. |
setHeader(name, value) |
Replaces values previously set for that header name. | You need to ensure the request has the new value rather than earlier values for that name. |
headers(String...) |
Accepts alternating header names and values. | A compact group of headers is clearer than a sequence of calls. |
Add values with header
Use header for a header that has not yet been set, or when adding another value is intentional:
HttpRequest request = HttpRequest.newBuilder(URI.create("https://example.com/api"))
.header("Accept", "application/json")
.header("X-Request-Id", "abc123")
.GET()
.build();
Repeated calls may result in multiple values for one field. Do not assume those values mean the same thing as one comma-joined value: interpretation depends on the semantics of the particular HTTP field, not on the builder method.
Replace values with setHeader
If code may already have added a value and the new one should replace it, use setHeader:
Rank #2
HttpRequest request = HttpRequest.newBuilder(URI.create("https://example.com/api"))
.header("X-Request-Id", "old-id")
.setHeader("X-Request-Id", "abc123")
.GET()
.build();
The resulting request uses the value set by the later setHeader call for that name instead of retaining the earlier value. Prefer this method when replacement is the intent; relying on accumulated values can cause confusing results.
Supply several fields with headers
For a short, fixed set of fields, the varargs convenience method takes alternating names and values:
HttpRequest request = HttpRequest.newBuilder(URI.create("https://example.com/api"))
.headers("Accept", "application/json", "X-Request-Id", "abc123")
.GET()
.build();
Keep the sequence paired: a name must be followed by its value. Use separate header calls if that is easier to read or if values are added conditionally. The available API documentation describes these as builder alternatives; it does not make different HTTP fields’ value semantics interchangeable.
Send headers with a request body
For a request with a body, add the headers on the same builder and provide a body publisher. For example, a JSON endpoint may expect an application-specific content type:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class PostExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String json = "{"name":"Ada"}";
HttpRequest request = HttpRequest.newBuilder(
URI.create("https://example.com/api/items"))
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("X-Request-Id", "abc123")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println(response.body());
}
}
The endpoint determines which application-level headers and body format it accepts. This example does not establish that a particular server accepts the request. Do not add a manually calculated Content-Length: the Java API notes that the request body publisher can determine that value, and the JDK may restrict user code from setting it.
Which headers can the JDK reject?
A builder call may throw IllegalArgumentException when a header name or value is invalid, or when the implementation restricts that field. Oracle’s Java SE 26 JDK module reference says these names are normally barred from being set directly by user code: connection, content-length, expect, host, and upgrade. Header names are case-insensitive in HTTP, so changing capitalization is not a way around a restriction.
Rank #4
The Java SE 21 HttpRequest.Builder reference likewise notes that implementations may reject invalid or restricted names and values, and gives Content-Length as an example of a field the client may determine itself. These details are version-specific documentation; do not assume that every JDK implementation or version has identical restriction behavior.
Why these fields are different
Some protocol fields are tied to how the client constructs and transmits the request. For instance, the body publisher can determine content length. Allowing application code to supply a conflicting value can produce a request whose declared metadata disagrees with what the client sends. The practical rule is to set application headers the endpoint requires, but leave client-managed transport fields to HttpClient.
Do not use the override property as a production workaround
The Java SE 26 module reference documents the system property jdk.httpclient.allowRestrictedHeaders, which takes a comma-separated list of names to override some default restrictions. Oracle labels this property as intended for testing and warns that overriding restrictions can lead to protocol errors or undefined behavior; other contextual restrictions may not be overridden. It is not a general-purpose production fix for a rejected header.
Recommended Free Tools
Best Value
Troubleshoot rejected or ineffective headers
- Check the exception first. If the builder throws
IllegalArgumentException, read its message and verify that the name and value are valid. A restricted field can also be the cause. - Check whether the client owns the field. In the Java SE 26 JDK documentation, the normally restricted names include
connection,content-length,expect,host, andupgrade. Do not try capitalization changes or a manualContent-Lengthas a workaround. - Confirm add versus replace intent. Use
headerwhen adding a value; usesetHeaderif earlier values for that name should be replaced. Multiple calls can add values rather than overwrite them. - Verify the server’s expected field and value. A request may build successfully while the endpoint still rejects or ignores a header it does not support. The endpoint’s contract—not the Java builder—defines what its application-level headers mean.
- Check the request you actually build. Ensure the header calls occur on the builder used for the request sent, and that you call
build()after setting them. If a request is reconstructed elsewhere, verify that the new builder receives the needed headers too.
These checks separate builder-time failures from server-side behavior. The first points to malformed or restricted input; the latter means the request was constructed but the endpoint’s response must be diagnosed against that service’s own requirements.
Or skip the browser setup
Java HttpClient is the right tool when your program needs to send a request with custom headers. If your task is instead to capture a website screenshot, ScreenshotNeo is a separate website screenshot API; it is not a Java HttpClient header feature. Its one-call GET endpoint accepts a URL and returns an image or PDF. See the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie/consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and whether the request was billed. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 screenshots a month without a card; paid plans start at $5 for 3,000 shots. Sign up for ScreenshotNeo’s free plan.
FAQ
Can I set headers on HttpClient itself?
The pattern shown here sets custom values on each HttpRequest.Builder. Use the builder for the request-specific headers you want sent, and avoid treating a request’s headers as client-wide settings.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Does header replace a value that was already set?
No. The documented behavior distinguishes header, which adds a value, from setHeader, which replaces previously set values for that name.
Can I send an Authorization header?
The builder methods accept header name/value pairs, but the specific authorization scheme, credential format, and endpoint requirements must come from the service you are calling. Do not place real secrets in shared code or logs.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

