Skip to content
Hopmind

Guides

How to send requests through a proxy in Java (HttpClient)

A request through an HTTP proxy with a login and password in java.net.http.HttpClient with ProxySelector and Authenticator.

What you need

The proxy is issued in the format host:port:login:password. Replace HOST, PORT, LOGIN and PASSWORD with your own values. Java 11 or newer is required: the java.net.http.HttpClient client appeared in it. No third-party libraries are needed.

Basic over an HTTPS tunnel

For HTTPS sites the client opens a tunnel through the proxy with the CONNECT command. The Java documentation describes the system property jdk.http.auth.tunneling.disabledSchemes: a list of authentication schemes disallowed for such a tunnel, and in the standard JDK distribution the conf/net.properties file lists the Basic scheme there. That is why in some JDK versions and configurations a request to an HTTPS site ends with error 407 even though the login and password are correct. If you run into this, start the program with the flag -Djdk.http.auth.tunneling.disabledSchemes= (an empty value allows Basic). Enable it only for a proxy you trust: the login and password go to the proxy itself in the clear, encoded only in base64. In our check on JDK 21 the request went through without the flag.

Example

The file ProxyExample.java. Run: java ProxyExample.java. If HTTPS returns 407, add the flag -Djdk.http.auth.tunneling.disabledSchemes= before the file name.
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class ProxyExample {
    private static final String HOST = "HOST";
    private static final String PORT = "PORT";
    private static final String LOGIN = "LOGIN";
    private static final String PASSWORD = "PASSWORD";

    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newBuilder()
            // Proxy over HTTP; for HTTPS sites the client opens the tunnel itself
            .proxy(ProxySelector.of(new InetSocketAddress(HOST, Integer.parseInt(PORT))))
            // We give the login and password only when the proxy asks for them
            .authenticator(new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    if (getRequestorType() == RequestorType.PROXY) {
                        return new PasswordAuthentication(LOGIN, PASSWORD.toCharArray());
                    }
                    return null;
                }
            })
            .connectTimeout(Duration.ofSeconds(15))
            .build();

        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.ipify.org"))
            .timeout(Duration.ofSeconds(30))
            .GET()
            .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // The service returns the address the request came from
        System.out.println(response.body());
    }
}

If SOCKS5

This guide does not describe SOCKS5 setup with a login and password for java.net.http.HttpClient, because we could not confirm it in the documentation. Use the proxy's HTTP port, as in the example above.

Common errors

  1. HTTP 407 or IOException: Unable to tunnel through proxy. Proxy returns HTTP/1.1 407: first check the login and password. If they are correct and the error occurs only on HTTPS sites, run the program with the flag -Djdk.http.auth.tunneling.disabledSchemes=.
  2. HttpConnectTimeoutException or HttpTimeoutException: check HOST and PORT, whether the SOCKS5 port was put into HTTP mode, and increase the timeouts.
  3. Special characters in the password: PasswordAuthentication takes the password as a char array without encoding, so nothing needs encoding.
  4. The https:// scheme in the proxy address: the client takes the proxy as an address and port without a scheme, and the proxy works over HTTP even for HTTPS sites.
  5. The Authenticator is also called for ordinary authentication on a site. The getRequestorType() == PROXY check stops the proxy password from being sent to a site.

Sources

Checked against the official documentation: October 2026. Program interfaces change: if item names differ, follow the documentation.

All guides are collected on the Guides page.

Find a proxy in the chat