Skip to content
Java HttpClient & OkHttp

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

Java's built-in client handles HTTP(S) proxies well once you know about the tunneling flag: since Java 8u111, Basic authentication is disabled for HTTPS tunnels by default, which is why so many first attempts end in a 407.
  • 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

Every CleanProxies product works over HTTP(S) and SOCKS5. This is what the dashboard gives you.
ProductLine in your dashboardNotes
Static ISP proxiesIP:PORT:USER:PASSOne line per dedicated IP. With IP whitelisting turned on, the line is just IP:PORT and no password is sent.
Rotating residential and mobileHOST:PORT:USER:PASSGenerated 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. 1

    Allow Basic auth for HTTPS tunnels

    Add -Djdk.http.auth.tunneling.disabledSchemes="" to the JVM options, or set it with System.setProperty before the first request.
  2. 2

    Set the proxy

    Use ProxySelector.of(new InetSocketAddress("HOST", PORT)) on the client builder.
  3. 3

    Add an Authenticator

    Return a PasswordAuthentication with your username and password when getRequestorType() is PROXY.
  4. 4

    Check the exit IP

    Send a GET to https://api.ipify.org and print the body.

java.net.http.HttpClient with proxy authentication

ProxyTest.javaJava
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.

OkHttp (Java)Java
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.

SOCKS5 with HttpURLConnectionJava
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

Both products use the same setup. What changes is how long an IP stays with you.

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.

Static ISP ProxiesAs low as $0.75/IP

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.

Rotating Residential ProxiesAs low as $0.63/GB

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

ProblemLikely causeFix
407 on HTTPS URLs onlyBasic auth is disabled for HTTPS tunneling by default.Set jdk.http.auth.tunneling.disabledSchemes to an empty string at JVM start.
HttpConnectTimeoutExceptionWrong host or port, or outbound traffic blocked.Test the line with curl -x, then check firewall rules on the server.
SSLHandshakeExceptionA TLS-inspecting firewall or an outdated JDK trust store.Update the JDK; the proxy tunnel doesn't change certificates.
SOCKS proxy ignored by HttpClientjava.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.

Get CleanProxies for Java

Super clean US ISP IPs from $0.75/IP with unlimited bandwidth, rotating residential from $0.63/GB and mobile from $0.79/GB. Instant delivery, 99.9% uptime and 24/7 support.