407 Proxy Authentication Required : Chaque cause et comment la résoudre

HTTP 407 a exactement une signification : le proxy devant vous a refusé vos identifiants. Ce simple fait élimine la plupart des fausses pistes — voici le reste de la carte.

HTTP 407 Proxy Authentication Required a exactement une signification, et elle est plus restreinte que la plupart des gens ne le pensent : un proxy entre vous et Internet a refusé la demande car il manque des identifiants valides pour le proxy lui-même. Le site cible n'a jamais été contacté. Il n'a jamais vu votre demande, n'a jamais pris de décision, et ne peut pas être la cause. Corriger un 407 signifie donc toujours corriger votre configuration de proxy — et la liste des choses qui peuvent être incorrectes est courte et entièrement énumérable. Ce guide parcourt toute la liste, avec les corrections spécifiques aux outils qui piègent le plus souvent les gens.

Lisez d'abord l'en-tête Proxy-Authenticate

Selon la spécification HTTP (RFC 9110), un 407 doit être accompagné d'un en-tête Proxy-Authenticate décrivant comment s'authentifier — typiquement quelque chose comme Proxy-Authenticate: Basic realm="Access to internal site". Votre client est alors censé répéter la demande avec un en-tête Proxy-Authorization. Ce couplage vaut la peine d'être mémorisé, car c'est ce qui distingue 407 de son voisin : un 401 provient du serveur d'origine et associe WWW-Authenticate avec Authorization, tandis que 407 provient d'un intermédiaire et utilise les versions préfixées par Proxy-. Si vous regardez un en-tête WWW-Authenticate, vous déboguez le mauvais saut.

# See exactly which hop is refusing you, and what scheme it wants
curl -v -x http://USER:PASS@gate.quantumproxies.io:8000 https://httpbin.org/ip

# Response you are looking for on failure:
#   HTTP/1.1 407 Proxy Authentication Required
#   Proxy-Authenticate: Basic realm="..."
#
# Response you want on success: your exit IP, not your own
#   {"origin": "203.0.113.45"}

Si curl -x avec des identifiants retourne votre IP de sortie, le proxy et les identifiants sont tous deux corrects — et tout 407 que vous voyez encore dans une application est dû à la configuration propre à cette application, pas à celle du proxy. Ce simple test divise le problème en deux en environ dix secondes.

Cause 1 : les identifiants sont absents, incorrects ou au mauvais endroit

La cause la plus courante est aussi la plus ennuyeuse. Les identifiants appartiennent à l'URL du proxy, avant l'hôte, sous la forme user:pass@host:port — et la bibliothèque cliente construit l'en-tête Proxy-Authorization à partir de ceux-ci. Copier un point de terminaison depuis un tableau de bord sans les identifiants, ou coller votre mot de passe de compte au lieu du mot de passe du proxy (ils sont généralement différents), produit un 407 immédiat et permanent à chaque demande.

import requests

proxy = "http://USER:PASS@gate.quantumproxies.io:8000"
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=15)
print(r.status_code, r.json())   # 200 and the exit IP = auth is correct

Vérifiez également le port. Les fournisseurs exposent différents ports pour les points de terminaison rotatifs et fixes, et pour HTTP par rapport à SOCKS5 ; frapper le mauvais avec des identifiants valides peut toujours retourner 407 car cet écouteur attend un format d'identité différent. Si vous n'êtes pas sûr du protocole que vous utilisez, notre explication sur les différences entre les proxies SOCKS5 et HTTP expose les différences.

Cause 2 : caractères spéciaux qui n'ont jamais été encodés en pourcentage

Celle-ci coûte aux gens des après-midis entiers. Une URL de proxy est une URL, donc tout caractère réservé dans votre nom d'utilisateur ou mot de passe doit être encodé en pourcentage ou le parseur divisera la chaîne au mauvais endroit. Un mot de passe contenant @ termine prématurément la section userinfo et votre client essaie de se connecter à un hôte qui n'existe pas ; un : divise le nom d'utilisateur du mot de passe au mauvais endroit.

from urllib.parse import quote

user = quote("team@example.com", safe="")   # team%40example.com
pwd  = quote("p@ss:w#rd", safe="")          # p%40ss%3Aw%23rd

proxy = f"http://{user}:{pwd}@gate.quantumproxies.io:8000"
Liste de contrôle mappant les symptômes de 407 proxy authentication required à leurs causes réelles, y compris les échecs de tunnel, les changements de liste blanche et les paramètres de proxy spécifiques à chaque outil
Même code d'état, six défauts différents. Associez le symptôme à gauche avant de changer quoi que ce soit.

Cause 3 : authentification par liste blanche et une IP qui a changé

La plupart des fournisseurs prennent en charge deux modes d'authentification : les identifiants dans l'URL, ou la liste blanche d'IP, où vous autorisez l'adresse publique de votre serveur dans le tableau de bord et n'envoyez aucun identifiant. QuantumProxies prend en charge les deux. Le mode de défaillance est spécifique et très reconnaissable : tout fonctionnait pendant des semaines, puis chaque demande a commencé à retourner 407 sans changement de code. C'est votre IP publique qui change — un renouvellement de bail DHCP au bureau, une nouvelle passerelle NAT après un redéploiement dans le cloud, un partage mobile, ou un coureur CI qui obtient une nouvelle adresse à chaque tâche.

Confirmez cela avant de déboguer quoi que ce soit d'autre : récupérez votre adresse publique actuelle avec curl -sS https://api.ipify.org, comparez-la à la liste blanche, et réajoutez-la si elle diffère. Si votre IP de sortie n'est pas stable — les coureurs CI et les groupes de mise à l'échelle automatique ne le sont généralement pas — passez cet environnement à l'authentification user:pass, qui voyage avec la configuration au lieu du réseau. L'autre moitié de ce piège est de mélanger les modes : certaines passerelles rejettent les identifiants sur un point de terminaison uniquement en liste blanche, donc envoyer les deux peut échouer là où n'en envoyer aucun réussit.

Cause 4 : HTTPS passe par un tunnel CONNECT

Un 407 qui n'apparaît que sur les URL https://, souvent sous forme de l'erreur Python OSError: Tunnel connection failed: 407 Proxy Authentication Required, a une cause structurelle. Les requêtes HTTP simples sont transmises par le proxy, mais les requêtes HTTPS ouvrent d'abord un tunnel avec une requête CONNECT — et ce CONNECT transporte son propre en-tête Proxy-Authorization. Si votre configuration n'a défini qu'un proxy HTTP, ou a défini des identifiants sur un schéma et pas l'autre, le tunnel est tenté anonymement et refusé avant même que TLS ne commence.

La règle est simple : configurez toujours les deux schémas avec les mêmes identifiants. En Python, cela signifie les deux clés dans le dictionnaire proxies ; dans le shell, cela signifie HTTP_PROXY et HTTPS_PROXY ; dans npm, cela signifie proxy et https-proxy. Notez que HTTPS_PROXY prend presque toujours un schéma http:// — le schéma décrit comment vous parlez au proxy, pas ce que vous récupérez à travers celui-ci.

// Node 18+ with undici: one dispatcher covers http and https targets
import { ProxyAgent, fetch } from "undici";

const dispatcher = new ProxyAgent(
  "http://USER:PASS@gate.quantumproxies.io:8000"
);

const res = await fetch("https://httpbin.org/ip", { dispatcher });
console.log(res.status, await res.json());

Cause 5 : l'outil a sa propre configuration de proxy

Les variables d'environnement ne sont pas universelles. De nombreux outils lisent leur propre fichier de configuration et ignorent complètement le shell, ce qui produit l'état exaspérant où curl fonctionne et votre build non. Un problème persistant avec GitHub Desktop est l'illustration parfaite : un développeur derrière un proxy d'entreprise avait défini le proxy dans .gitconfig et dans l'environnement, mais la connexion échouait toujours avec un 407 et net::ERR_TUNNEL_CONNECTION_FAILED — car la configuration git n'authentifiait que git, tandis que le navigateur intégré effectuant le flux OAuth n'avait pas ses propres identifiants de proxy. Chaque sous-système doit être configuré séparément.

# shell-wide (respected by curl, wget, pip, most SDKs)
export HTTP_PROXY="http://USER:PASS@gate.quantumproxies.io:8000"
export HTTPS_PROXY="$HTTP_PROXY"
export NO_PROXY="localhost,127.0.0.1,.internal"

# npm - both keys, or https installs will 407
npm config set proxy       "$HTTP_PROXY"
npm config set https-proxy  "$HTTPS_PROXY"

# git
git config --global http.proxy  "$HTTP_PROXY"
git config --global https.proxy "$HTTPS_PROXY"

# apt - /etc/apt/apt.conf.d/95proxies
# Acquire::http::Proxy  "http://USER:PASS@gate.quantumproxies.io:8000";
# Acquire::https::Proxy "http://USER:PASS@gate.quantumproxies.io:8000";

Une note de sécurité pendant que vous éditez tous ces fichiers : les identifiants dans un fichier git ou npm global finissent en texte clair, et les URL de proxy avec des mots de passe intégrés fuient dans l'historique du shell, les journaux CI et les traces d'erreur. Sur les machines avec une adresse stable, la liste blanche d'IP évite complètement le secret.

Comparaison de l'authentification proxy user:pass par rapport à la liste blanche d'IP, montrant les compromis de portabilité et de gestion des secrets
Les identifiants voyagent avec votre configuration ; les listes blanches voyagent avec votre réseau. Choisissez par environnement, jamais les deux à la fois.

Un 407 n'est jamais la faute du site cible

Cela vaut la peine de le répéter, car cela vous évite de courir après des fantômes. Si vous obtenez des 407, aucun changement d'agents utilisateurs, ajout d'en-têtes ou changement de pays de sortie ne vous aidera — la demande n'a pas encore quitté votre proxy. Les blocages qui proviennent du site cible sont différents : un 403 Forbidden signifie que le site vous a refusé, et un 429 Too Many Requests signifie que vous êtes allé trop vite. Diagnostiquez lequel des trois vous avez réellement avant d'écrire du code. Et si Python lance ProxyError ou SSLError plutôt qu'un 407 propre, notre guide sur le débogage de ProxyError dans Requests couvre les échecs au niveau du transport.

Questions fréquemment posées

Comment résoudre 407 Proxy Authentication Required ?

Mettez des identifiants valides dans l'URL du proxy sous la forme http://user:pass@host:port, en encodant en pourcentage tout caractère réservé, et configurez à la fois les paramètres de proxy HTTP et HTTPS. Si votre fournisseur utilise plutôt la liste blanche d'IP, autorisez votre IP publique actuelle et n'envoyez aucun identifiant. Vérifiez avec curl -x contre un service d'écho IP avant de toucher à votre code d'application.

Que signifie 407 Proxy Authentication Required ?

Cela signifie qu'un proxy intermédiaire a refusé la demande par manque d'identifiants proxy valides. La réponse inclut un en-tête Proxy-Authenticate nommant le schéma, et le client est censé réessayer avec Proxy-Authorization. Il est distinct de 401, qui provient du serveur de destination plutôt que du proxy intermédiaire.

Comment corriger l'erreur npm 407 ?

Définissez les deux clés : npm config set proxy et npm config set https-proxy, chacune avec l'URL complète http://user:pass@host:port. Le trafic du registre est HTTPS, donc un paramètre uniquement HTTP échoue au tunnel CONNECT. Encodez en pourcentage les caractères spéciaux dans le mot de passe, et vérifiez s'il y a un .npmrc au niveau du projet qui remplace votre configuration globale.

Pourquoi Python génère-t-il Tunnel connection failed: 407 ?

Parce que la requête HTTPS a ouvert un tunnel CONNECT qui n'a pas transporté d'identifiants de proxy. Définissez à la fois les clés http et https du dictionnaire proxies sur la même URL authentifiée. Vérifiez également si HTTP_PROXY ou HTTPS_PROXY dans l'environnement remplace votre dictionnaire — définissez session.trust_env = False pour écarter cette possibilité.

Comment configurer l'authentification proxy dans Postman ?

Ouvrez les Paramètres, allez à l'onglet Proxy, activez la configuration de proxy personnalisée, entrez l'hôte et le port, puis cochez la case d'authentification proxy et ajoutez le nom d'utilisateur et le mot de passe. Compter sur le basculement du proxy système est l'erreur habituelle — il route le trafic à travers le proxy mais ne fournit jamais les identifiants, donc chaque demande retourne 407.

Cinq causes couvrent essentiellement chaque 407 dans la nature : identifiants manquants, caractères spéciaux non encodés, une IP en liste blanche qui a changé, un tunnel CONNECT non authentifié, et un outil avec sa propre configuration. Travaillez-les dans cet ordre et le code d'état disparaît — alors vous pouvez commencer à vous soucier de ce que le site cible pense de vous.

Obtenez des proxies résidentiels avec authentification user:pass ou liste blanche d'IP