Every request comes back 407 Proxy Authentication Required, nothing reaches the target, and the credentials look right in the panel. It is one of the most common support tickets in this product category and also one of the fastest to resolve, because the number of things that can produce a 407 is small and they can be eliminated in a fixed order.
Here is what the status code actually means, the causes worth checking, the order to check them in, and the client-specific mistakes that produce a 407 even when the credentials are correct.
What a 407 actually is
A 407 comes from the proxy, not from the site you are trying to reach. It is the proxy’s way of saying that the request arrived without acceptable credentials, and it is the proxy-layer equivalent of a 401 from an origin server. That distinction matters for debugging: a 407 means your traffic reached the gateway and the gateway declined it. Connectivity is fine. Authentication is not.
It also means the target site has no involvement. If you are getting 407s, nothing you change about headers, user agents, rendering, or pacing will help, because your request never left the proxy.
The three causes worth checking first
On a gateway where targeting is expressed in the username, nearly every 407 is one of three things.
The credentials are wrong. A typo, a stray whitespace character copied from a dashboard, or credentials from a different product. Proxy credentials are usually not the same as your account login, which is a surprisingly common mix-up.
A flag in the extended username is malformed. This is the cause people miss, and it is specific to gateways that encode targeting in the username. If your username carries country, city, session, or TTL flags, an unrecognised value makes the whole username unparseable, and the gateway rejects it as an authentication failure rather than as a targeting error. A mistyped country code, a city slug in the wrong format, a session identifier with illegal characters, or a ttl without an accompanying sid all land here. The credentials are perfect; the username string is not.
The password was rotated. If someone regenerated it in the panel, every client still holding the old value returns 407 until it is updated. This is the classic case where it works on one machine and fails on another.
The diagnostic order
Work down this list and stop when it works, because the step that fixes it identifies the cause.
One: strip every flag and test the bare credentials. This single step separates a credential problem from a flag problem, and it should always be first.
# bare username, no targeting flags at all
curl -x customer-USERNAME:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
If that succeeds, your credentials are fine and the fault is in the flags. If it still returns 407, the credentials themselves are wrong and no amount of flag-fixing will help.
Two: add flags back one at a time. Country first, then city or ASN, then session and TTL. The flag that reintroduces the 407 is the malformed one, and you now know exactly which value to check.
curl -x customer-USERNAME-country-us:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
curl -x customer-USERNAME-country-us-city-new_york:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
curl -x customer-USERNAME-country-us-city-new_york-sid-abc123:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
Watch the formats: country codes are two-letter ISO codes, so uk is a common mistake where gb is correct. City slugs use underscores rather than spaces or hyphens, as in new_york. And ttl is only valid alongside sid, so a TTL on its own is invalid. The full syntax is in the gateway and authentication docs, and the targeting options are covered in city-level targeting and ASN targeting.
Three: re-copy the password from the panel. If bare credentials failed at step one, take the password directly from the panel rather than from your notes or a config file, and check specifically for a trailing space, a smart quote from a document, or a truncated paste.
Four: roll the value out everywhere. If it works locally but not in production, you have a stale copy in an environment variable, a secrets manager, a container image, or a CI configuration. This is a deployment problem rather than a proxy problem.
Errors that look like 407 but are not
Distinguishing these saves a lot of wasted effort, because each has a different fix.
A 502 on this gateway means no addresses matched your filter at that moment. That is a targeting problem, not an auth problem: your credentials were accepted and then nothing was available for the combination you asked for. Broaden the filter, drop from city to country, or relax a strict-match flag.
A 509 means plan bandwidth is exhausted with overage disabled. Authentication succeeded; you are out of quota. Related sizing guidance is in estimating monthly bandwidth.
Connection refused means you never reached the gateway, usually because you are pointing at a legacy port-based host rather than the current endpoint, or because egress from your network is blocked. Test raw connectivity with nc -vz p.shifter.io 443 before assuming an auth issue.
A 403 or a challenge page from the target means authentication worked perfectly and the site declined you, which is a completely different problem addressed by avoiding blocks.
Client-specific mistakes that produce a 407
Sometimes the credentials and flags are both correct and the client is at fault.
Special characters in the password. If the password contains characters that are meaningful in a URL, @, :, #, /, or %, embedding it directly in a proxy URL breaks the parse and the credentials arrive mangled. Percent-encode it.
import requests
from urllib.parse import quote
user = "customer-USERNAME-country-us"
pwd = quote("p@ss:word/123", safe="") # encode before embedding
PROXY = f"http://{user}:{pwd}@p.shifter.io:443"
r = requests.get("https://ipinfo.io/json",
proxies={"http": PROXY, "https": PROXY}, timeout=15)
print(r.status_code, r.text[:120])
Confusing proxy auth with target auth. curl -U sets proxy credentials; -u sets credentials for the target site. Sending your proxy credentials as an Authorization header does nothing, because proxy auth travels in Proxy-Authorization, and most clients set that for you when credentials are in the proxy URL.
Credentials dropped on HTTPS. Some client configurations set the proxy for HTTP only, so plain requests authenticate and HTTPS requests do not. Set both entries, as in the Python example above.
Environment variables that are not what you think. HTTP_PROXY and HTTPS_PROXY set in a shell profile, a Dockerfile, or a CI runner can silently override what your code passes, so an application can authenticate against a completely different proxy string than the one in your source. Print the effective proxy configuration when debugging rather than trusting the code.
A library that does not send preemptive proxy auth. A few HTTP clients wait to be challenged before sending credentials and mishandle the challenge, particularly with certain tunnelling setups. If a bare curl works and your application does not, the difference is in the client, not the gateway. The working configurations for common stacks are in using residential proxies with Python.
Handling 407 in production code
One operational note: a 407 is a terminal error, not a transient one. Retrying it is pointless, because the credentials will be equally wrong on the next attempt, and a retry loop against an auth failure just burns bandwidth and can look like a credential-stuffing pattern from the outside. Classify it as terminal, fail loudly, and alert, which is the classification discipline in retry and backoff.
Rotating credentials deserves a deployment plan rather than a panel click, since every client holding the old value starts failing at the moment of rotation. Update the secret store first, roll clients, then rotate.
The bottom line
A 407 means your request reached the gateway and the gateway rejected the credentials, so the target site is irrelevant and connectivity is proven. Test bare credentials with no flags first, because that single step splits the problem in half, then add flags back one at a time to find the malformed one, remembering that a bad country code or a TTL without a session makes the entire username unparseable. Re-copy the password from the panel if the bare test failed, and check for stale values in environment variables and secret stores if it works in one place and not another. Rule out the lookalikes: 502 is an empty filter, 509 is bandwidth, connection refused is the wrong host, and a 403 from the site is not an auth problem at all. And never retry a 407.
The full syntax reference is in the gateway and authentication docs, and the product itself is residential proxies, where the same credentials work across every country, city, and session mode with per-GB pricing.