Skip to content
Hopmind

Guides

How to send requests through a proxy in Go (net/http)

A request through an HTTP proxy and SOCKS5 with a login and password in Go using net/http and golang.org/x/net/proxy.

What you need

The proxy is issued in the format host:port:login:password. Replace HOST, PORT, LOGIN and PASSWORD with your own values. For an HTTP proxy the standard library is enough. For SOCKS5 you need the golang.org/x/net/proxy package.

go get golang.org/x/net/proxy

Example

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"time"
)

func main() {
	// We put the login and password in the struct; url.UserPassword encodes special characters itself.
	// The proxy scheme is http, including for HTTPS sites
	proxyURL := &url.URL{
		Scheme: "http",
		Host:   "HOST:PORT",
		User:   url.UserPassword("LOGIN", "PASSWORD"),
	}

	client := &http.Client{
		Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
		// Without a timeout a request can wait forever
		Timeout: 30 * time.Second,
	}

	resp, err := client.Get("https://api.ipify.org")
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	// The service returns the address the request came from
	fmt.Println(string(body))
}

If SOCKS5

SOCKS5 needs a dialer from golang.org/x/net/proxy. The login and password are passed with the proxy.Auth struct, so they need no encoding.

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"time"

	"golang.org/x/net/proxy"
)

func main() {
	auth := &proxy.Auth{User: "LOGIN", Password: "PASSWORD"}

	// The address of the proxy's SOCKS5 port, not the HTTP port
	dialer, err := proxy.SOCKS5("tcp", "HOST:SOCKS_PORT", auth, proxy.Direct)
	if err != nil {
		log.Fatal(err)
	}

	contextDialer, ok := dialer.(proxy.ContextDialer)
	if !ok {
		log.Fatal("dialer does not support context")
	}

	client := &http.Client{
		Transport: &http.Transport{DialContext: contextDialer.DialContext},
		Timeout:   30 * time.Second,
	}

	resp, err := client.Get("https://api.ipify.org")
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(body))
}

Common errors

  1. Proxy Authentication Required (407): the login or password is wrong. Check the order in the issued host:port:login:password.
  2. context deadline exceeded or i/o timeout: check HOST and PORT, whether the SOCKS5 port was put into HTTP mode, and increase Timeout.
  3. Special characters in the password: with url.UserPassword and proxy.Auth nothing needs encoding. Do not build the address as a string from the login and password: url.UserPassword encodes the values correctly.
  4. The https:// scheme in the proxy address: the issued proxy works over HTTP, so use the value http in the Scheme field, even for HTTPS sites.
  5. If Transport.Proxy is set, the HTTP_PROXY and HTTPS_PROXY environment variables are not used. If Proxy is not set in a hand-made Transport, no proxy is applied at all.

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