How to use proxies in Java
In Java 11+, build an HttpClient with .proxy(ProxySelector.of(new InetSocketAddress("HOST", PORT))) and an Authenticator that returns your username and password, then start the JVM with -Djdk.http.auth.tunneling.disabledSchemes="" so Basic proxy auth is allowed for HTTPS sites.
What you need
- An active CleanProxies plan: static ISP proxies for fixed US IPs, or rotating residential / mobile proxies for pools. The trial works too.
- Your credential line from the dashboard's proxy manager: host (or IP), port, username and password.
- Java 11 or later for
java.net.http.HttpClient(17 or 21 LTS recommended). - Optional: OkHttp 4 or 5 for the OkHttp example.
New to proxies? For the overview, read Using proxies with cURL, Python and Node.js and SOCKS5 vs HTTP proxies. This guide goes deeper on Java only.
Your CleanProxies credentials
| Product | Line in your dashboard | Notes |
|---|---|---|
| Static ISP proxies | IP:PORT:USER:PASS | One line per dedicated IP. With IP whitelisting turned on, the line is just IP:PORT and no password is sent. |
| Rotating residential and mobile | HOST:PORT:USER:PASS | Generated in the proxy manager. The username carries the location and session you pick, so generate a new list to change them. |
Most tools want the same details as a URL: http://USERNAME:PASSWORD@HOST:PORT for HTTP(S) or socks5://USERNAME:PASSWORD@HOST:PORT for SOCKS5. The examples on this page use those placeholders; copy the host, port, username and password from your CleanProxies dashboard. To convert a whole list at once, paste it into the proxy list formatter.
How to set up CleanProxies in Java
- 1
Allow Basic auth for HTTPS tunnels
Add-Djdk.http.auth.tunneling.disabledSchemes=""to the JVM options, or set it withSystem.setPropertybefore the first request. - 2
Set the proxy
UseProxySelector.of(new InetSocketAddress("HOST", PORT))on the client builder. - 3
Add an Authenticator
Return aPasswordAuthenticationwith your username and password whengetRequestorType()isPROXY. - 4
Check the exit IP
Send a GET tohttps://api.ipify.organd print the body.
java.net.http.HttpClient with proxy authentication
import java.net.*;
import java.net.http.*;
import java.time.Duration;
public class ProxyTest {
public static void main(String[] args) throws Exception {
// Allow Basic auth on HTTPS tunnels (disabled by default since 8u111).
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
HttpClient client = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress("HOST", PORT)))
.authenticator(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType() == RequestorType.PROXY) {
return new PasswordAuthentication("USERNAME", "PASSWORD".toCharArray());
}
return null;
}
})
.connectTimeout(Duration.ofSeconds(15))
.build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.ipify.org")).build();
System.out.println(client.send(request, HttpResponse.BodyHandlers.ofString()).body());
}
}The property must be set before the HTTP client classes read it, so the command-line flag is the safer option in production: java -Djdk.http.auth.tunneling.disabledSchemes="" -jar app.jar.
OkHttp with a proxy authenticator
OkHttp answers the proxy's 407 challenge through proxyAuthenticator, without any JVM flags.
OkHttpClient client = new OkHttpClient.Builder()
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("HOST", PORT)))
.proxyAuthenticator((route, response) -> response.request().newBuilder()
.header("Proxy-Authorization", Credentials.basic("USERNAME", "PASSWORD"))
.build())
.build();
Request request = new Request.Builder().url("https://api.ipify.org").build();
try (Response response = client.newCall(request).execute()) {
System.out.println(response.body().string());
}SOCKS5 in Java
java.net.http.HttpClient only speaks to HTTP proxies. For SOCKS5, use HttpURLConnection (or OkHttp) with a Proxy.Type.SOCKS proxy; the SOCKS username and password come from the default Authenticator.
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("USERNAME", "PASSWORD".toCharArray());
}
});
Proxy socks = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("HOST", PORT));
HttpURLConnection conn = (HttpURLConnection) URI.create("https://api.ipify.org").toURL().openConnection(socks);
System.out.println(new String(conn.getInputStream().readAllBytes()));Static ISP vs rotating residential in Java
Static ISP proxies
One HttpClient per ISP line gives each worker its own dedicated US IP. Clients are thread-safe and pool connections, so build them once at startup.
Rotating residential proxies
HttpClient keeps connections alive, so a rotating residential line may reuse one exit IP across requests. Generate a sticky list for flows that must stay on one IP, and open a new client (or close idle connections) when you want a fresh IP.
Verify your exit IP
Run ProxyTest and compare the printed IP with the line in your dashboard. A 407 at this point almost always means the tunneling flag wasn't applied.
Open What is my IP? through the proxy to see the address and headers a website receives, or paste up to ten lines into the free proxy checker to test connectivity, latency and exit IP before you start.
Troubleshooting Java proxy errors
| Problem | Likely cause | Fix |
|---|---|---|
| 407 on HTTPS URLs only | Basic auth is disabled for HTTPS tunneling by default. | Set jdk.http.auth.tunneling.disabledSchemes to an empty string at JVM start. |
| HttpConnectTimeoutException | Wrong host or port, or outbound traffic blocked. | Test the line with curl -x, then check firewall rules on the server. |
| SSLHandshakeException | A TLS-inspecting firewall or an outdated JDK trust store. | Update the JDK; the proxy tunnel doesn't change certificates. |
| SOCKS proxy ignored by HttpClient | java.net.http.HttpClient doesn't support SOCKS. | Use HttpURLConnection or OkHttp with Proxy.Type.SOCKS. |
Still stuck? Our 24/7 support team answers fast: contact us with the error and the line you used (leave the password out).
Java proxy FAQs
Since Java 8u111 the JDK refuses to send Basic credentials when tunneling HTTPS through a proxy. Set the system property jdk.http.auth.tunneling.disabledSchemes to an empty string at startup and the same code authenticates.