A proxy is five pieces of information: a scheme, a username, a password, a host and a port. Providers, tools and forums arrange those pieces in different orders, and a proxy that works in one tool fails in another just because it was pasted in the wrong shape. This guide shows the common layouts, which tools expect which, and how to avoid the mistakes we see most often with residential proxies.
The five common layouts
Here is the same Shifter proxy in the five formats our dashboard’s Proxy Generator can produce. The username carries the targeting and the session, so it is longer than you might expect.
| Format | Example |
|---|---|
scheme://user:pass@host:port | http://customer-USERNAME-sid-a1-ttl-60:PASSWORD@p.shifter.io:443 |
user:pass@host:port | customer-USERNAME-sid-a1-ttl-60:PASSWORD@p.shifter.io:443 |
host:port:user:pass | p.shifter.io:443:customer-USERNAME-sid-a1-ttl-60:PASSWORD |
user:pass:host:port | customer-USERNAME-sid-a1-ttl-60:PASSWORD:p.shifter.io:443 |
host:port@user:pass | p.shifter.io:443@customer-USERNAME-sid-a1-ttl-60:PASSWORD |
The first is a real URL, defined by web standards, and it is the safest choice whenever a tool accepts it. The others are conventions. They exist because many bulk tools import plain text lists, one proxy per line, and each tool picked its own order.
Which tools expect which
curl. Pass the URL form to -x. If you leave out the scheme, curl assumes http://. You can also keep the credentials separate with -U username:password, which avoids encoding problems. Our guide to curl and Postman setup has full examples.
Python requests and Scrapy. Both take the URL form. In requests, the dictionary keys name the scheme of the website, and the values name the proxy, so both usually point at an http:// proxy:
proxy = "http://customer-USERNAME:PASSWORD@p.shifter.io:443"
proxies = {"http": proxy, "https": proxy}
Playwright. Takes the parts as separate fields: server with scheme, host and port, plus username and password. Splitting them yourself avoids every encoding issue.
Puppeteer and Chrome. The --proxy-server flag takes host and port only. Credentials go through page.authenticate().
Browser profile managers and bulk tools. Many import lists in host:port:user:pass, and some ask which order your list uses. Check the import screen before pasting a few hundred lines.
The scheme describes the proxy, not the website
This is the most common mistake we see. A customer scraping HTTPS websites writes https:// in front of the proxy, and every request fails with a TLS error.
The scheme tells your client how to talk to the proxy. An HTTPS website is reached through an http:// proxy with the CONNECT method: the client asks the proxy to open a tunnel, then runs TLS with the website through it. The connection to the website is still encrypted end to end. Writing https://p.shifter.io:443 asks the client to start TLS with the gateway itself, and our gateway does not offer that, so the handshake fails. Use http:// for HTTP and HTTPS sites alike, or socks5:// if your tool prefers SOCKS.
With SOCKS there is a second choice. socks5:// resolves the website’s name on your machine, while socks5h:// sends the name to the proxy to resolve. If you care where DNS lookups happen, read our guide to preventing DNS leaks.
Special characters break formats
Each format reserves some characters.
- URL form:
@,:,/,#,?and%inside a username or password must be percent-encoded. A password likep@ss:wordbecomesp%40ss%3Aword. - Colon-separated forms: a colon inside the password moves every field after it, so the tool reads the wrong host or port.
The targeting and session parts of a Shifter username use only letters, digits, dashes and underscores, for example city-new_york, so they are safe in every format. If you set a password with symbols, the URL form with encoding, or a tool with separate fields, is the reliable route.
Converting between formats
When a tool gives you one format and your code wants another, convert the list rather than editing lines by hand. This Python function turns any of the five layouts into the URL form and encodes the credentials:
from urllib.parse import quote
def to_proxy_url(line: str, scheme: str = "http") -> str:
line = line.strip()
if "://" in line:
return line
if "@" in line:
left, right = line.split("@", 1)
if left.rsplit(":", 1)[-1].isdigit():
hostport, creds = left, right # host:port@user:pass
else:
creds, hostport = left, right # user:pass@host:port
user, password = creds.split(":", 1)
host, port = hostport.rsplit(":", 1)
else:
parts = line.split(":")
if len(parts) != 4:
raise ValueError(f"unrecognised proxy line: {line}")
if parts[1].isdigit():
host, port, user, password = parts # host:port:user:pass
else:
user, password, host, port = parts # user:pass:host:port
return f"{scheme}://{quote(user, safe='')}:{quote(password, safe='')}@{host}:{port}"
print(to_proxy_url("p.shifter.io:443:customer-USERNAME:PASSWORD"))
# http://customer-USERNAME:PASSWORD@p.shifter.io:443
It decides the order by finding the port number, so it cannot tell the layouts apart when a username or password is all digits. In that case, ask whoever gave you the list which order it uses.
ISP proxies use the same shapes
ISP proxies follow the same rules with a different host. Every ISP proxy connects through isp.shifter.io:443, so a line in host:port:user:pass form reads isp.shifter.io:443:USERNAME:PASSWORD. Each proxy is told apart by its username, not by a separate IP and port per proxy, which surprises people used to lists of ip:port:user:pass.
Quick checks when a proxy will not connect
- 407 Proxy Authentication Required: the proxy was reached but the credentials were not accepted. Check for a missing or swapped username and password, or an unencoded symbol. Our 407 troubleshooting guide covers the rest.
- TLS or handshake errors right away: you probably wrote
https://in front of the proxy. Change it tohttp://. - Connection refused or timeouts on every request: the host or port is wrong, often because a colon-separated line was read in the wrong order.
- Works in curl, fails in your tool: the tool expects a different layout. Convert the line, or enter the fields separately.
In the dashboard, the Proxy Generator lets you pick the protocol and the format before you copy, and it downloads a whole list as CSV in the same format. Choosing the right shape at the start avoids most of these errors.
Sources and references
- RFC 3986, Uniform Resource Identifier: Generic Syntax: rfc-editor.org
- curl, the —proxy option: curl.se
- Requests, proxies: requests.readthedocs.io
- Playwright, HTTP proxy: playwright.dev