407 프록시 인증 필요: 모든 원인과 해결 방법
HTTP 407은 정확히 하나의 의미를 가집니다: 앞에 있는 프록시가 당신의 자격 증명을 거부했습니다. 이 단일 사실은 대부분의 잘못된 방향을 제거합니다 — 여기에 나머지 지도가 있습니다.
HTTP 407 Proxy Authentication Required는 정확히 하나의 의미를 가지며, 대부분 사람들이 생각하는 것보다 좁습니다: 당신과 인터넷 사이에 있는 프록시가 유효한 자격 증명이 부족하여 요청을 거부했습니다 프록시 자체에 대한. 대상 웹사이트는 절대 접촉되지 않았습니다. 요청을 본 적도 없고, 결정을 내린 적도 없으며, 원인이 될 수 없습니다. 따라서 407을 수정하는 것은 항상 프록시 구성을 수정하는 것을 의미하며, 잘못될 수 있는 것들의 목록은 짧고 완전히 열거 가능합니다. 이 가이드는 그 전체 목록을 안내하며, 사람들을 가장 많이 혼란스럽게 하는 도구별 수정 사항을 포함합니다.
먼저 Proxy-Authenticate 헤더를 읽으세요
HTTP 사양(RFC 9110)에 따르면, 407은 Proxy-Authenticate 헤더와 함께 제공되어야 하며, 이는 인증 방법을 설명합니다 — 일반적으로 Proxy-Authenticate: Basic realm="Access to internal site"와 같은 것입니다. 그런 다음 클라이언트는 Proxy-Authorization 헤더와 함께 요청을 반복해야 합니다. 이 쌍은 암기할 가치가 있습니다, 왜냐하면 이것이 407을 이웃과 구별하는 것이기 때문입니다: 401은 원본 서버에서 오며 WWW-Authenticate와 Authorization을 쌍으로 사용하고, 407은 중간에서 오며 Proxy- 접두사가 붙은 버전을 사용합니다. WWW-Authenticate 헤더를 보고 있다면, 잘못된 홉을 디버깅하고 있는 것입니다.
# 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"}
curl -x가 자격 증명과 함께 당신의 종료 IP를 반환하면, 프록시와 자격 증명은 모두 괜찮습니다 — 그리고 여전히 애플리케이션에서 407을 보는 경우, 그것은 애플리케이션 자체의 구성 문제이지 프록시의 문제가 아닙니다. 이 단일 테스트는 문제를 약 10초 만에 반으로 나눕니다.
원인 1: 자격 증명이 없거나, 잘못되었거나, 잘못된 위치에 있습니다
가장 흔한 원인은 또한 가장 지루한 것입니다. 자격 증명은 프록시 URL에 속하며, 호스트 앞에 user:pass@host:port 형식으로 있어야 합니다 — 그리고 클라이언트 라이브러리는 그것으로부터 Proxy-Authorization 헤더를 만듭니다. 대시보드에서 자격 증명 없이 엔드포인트를 복사하거나, 계정 비밀번호 대신 프록시 비밀번호를 붙여넣는 것은 (보통 다릅니다) 모든 요청에서 즉각적이고 영구적인 407을 발생시킵니다.
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
포트도 확인하세요. 제공자는 회전 및 고정 엔드포인트에 대해, 그리고 HTTP와 SOCKS5에 대해 다른 포트를 노출합니다; 올바른 자격 증명을 가지고도 잘못된 포트를 사용하면 여전히 407을 반환할 수 있습니다, 왜냐하면 그 리스너는 다른 신원 형식을 기대하기 때문입니다. 어떤 프로토콜을 사용 중인지 확신이 없다면, 우리의 SOCKS5 대 HTTP 프록시 설명서를 참조하세요.
원인 2: 퍼센트 인코딩되지 않은 특수 문자
이것은 사람들에게 전체 오후를 소모하게 만듭니다. 프록시 URL은 URL이므로, 사용자 이름이나 비밀번호에 있는 모든 예약된 문자는 퍼센트 인코딩되어야 하며, 그렇지 않으면 파서가 문자열을 잘못된 위치에서 분할합니다. @가 포함된 비밀번호는 사용자 정보 섹션을 일찍 끝내고, 클라이언트는 존재하지 않는 호스트에 연결하려고 시도합니다; :는 사용자 이름과 비밀번호를 잘못된 위치에서 분리합니다.
@는%40이 됩니다 — 가장 흔한 범인, 이메일이 사용자 이름으로 사용되기 때문입니다.:는%3A가 됩니다 — 그렇지 않으면 사용자 이름/비밀번호 구분자로 읽힙니다.#는%23가 됩니다 — 이후의 모든 것이 조각으로 처리되어 조용히 삭제됩니다./는%2F가 되고?는%3F가 됩니다 — 둘 다 권한 섹션을 끝냅니다.- 공백은
%20이 됩니다. 비밀번호에 공백이 있다면, 대신 변경하세요.
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"

원인 3: 화이트리스트 인증 및 이동된 IP
대부분의 제공자는 두 가지 인증 모드를 지원합니다: URL에 자격 증명을 포함하거나, IP 화이트리스트를 사용하여 서버의 공용 주소를 대시보드에서 승인하고 자격 증명을 전혀 보내지 않습니다. QuantumProxies는 둘 다 지원합니다. 실패 모드는 특정하고 매우 인식 가능합니다: 몇 주 동안 모든 것이 잘 작동하다가, 코드 변경 없이 모든 요청이 407을 반환하기 시작했습니다. 그것은 당신의 공용 IP가 변경된 것입니다 — 사무실에서 DHCP 임대 갱신, 클라우드 재배포 후 새로운 NAT 게이트웨이, 모바일 테더링, 또는 매 작업마다 새로운 주소를 받는 CI 러너.
다른 것을 디버깅하기 전에 그것을 확인하세요: curl -sS https://api.ipify.org로 현재 공용 주소를 가져와 화이트리스트와 비교하고, 다르면 다시 추가하세요. 당신의 이그레스 IP가 안정적이지 않다면 — CI 러너와 자동 확장 그룹은 거의 그렇지 않습니다 — 그 환경을 user:pass 인증으로 전환하세요, 이는 네트워크 대신 구성과 함께 이동합니다. 이 함정의 다른 절반은 모드를 혼합하는 것입니다: 일부 게이트웨이는 화이트리스트 전용 엔드포인트에서 자격 증명을 거부하므로, 둘 다 보내면 아무 것도 보내지 않을 때 성공하는 곳에서 실패할 수 있습니다.
원인 4: HTTPS가 CONNECT 터널을 통과합니다
https:// URL에서만 나타나는 407, 종종 Python 오류 OSError: Tunnel connection failed: 407 Proxy Authentication Required로 나타나는 것은 구조적 원인이 있습니다. 일반 HTTP 요청은 프록시에 의해 전달되지만, HTTPS 요청은 먼저 CONNECT 요청으로 터널을 엽니다 — 그리고 그 CONNECT는 자체 Proxy-Authorization 헤더를 가집니다. 당신의 구성에서 HTTP 프록시만 설정했거나, 한 스킴에만 자격 증명을 설정한 경우, 터널은 익명으로 시도되고 TLS가 시작되기 전에 거부됩니다.
규칙은 간단합니다: 항상 동일한 자격 증명으로 두 스킴을 구성하세요. Python에서는 proxies dict의 두 키 모두를 의미합니다; 셸에서는 HTTP_PROXY와 HTTPS_PROXY를 의미합니다; npm에서는 proxy와 https-proxy를 의미합니다. HTTPS_PROXY는 거의 항상 http:// 스킴을 사용합니다 — 스킴은 프록시와 통신하는 방법을 설명하며, 프록시를 통해 가져오는 것을 설명하지 않습니다.
// 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());
원인 5: 도구가 자체 프록시 구성을 가지고 있습니다
환경 변수는 보편적이지 않습니다. 많은 도구가 자체 구성 파일을 읽고 셸을 완전히 무시하여, curl은 작동하지만 빌드는 작동하지 않는 짜증나는 상태를 만듭니다. 장기적인 GitHub Desktop 문제는 교과서적인 예시입니다: 기업 프록시 뒤에 있는 개발자가 .gitconfig와 환경에 프록시를 설정했지만, 로그인은 여전히 407과 net::ERR_TUNNEL_CONNECTION_FAILED로 실패했습니다 — 왜냐하면 git 구성은 git만 인증했으며, OAuth 흐름을 수행하는 내장 브라우저는 자체 프록시 자격 증명이 없었기 때문입니다. 모든 하위 시스템은 별도로 알려줘야 합니다.
# 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";
- Postman — 설정, 프록시, 사용자 정의 프록시 구성, 그런 다음 프록시 인증을 선택하고 사용자 이름과 비밀번호를 입력하세요. 시스템 프록시 토글은 자격 증명을 전달하지 않습니다.
- .NET / C# — "원격 서버가 오류를 반환했습니다: (407)"라는
WebException은WebProxy에Credentials이 없음을 의미합니다; 명시적으로 설정하거나 기본 네트워크 자격 증명을 사용하세요. - Java —
http.proxyUser와http.proxyPassword시스템 속성, 그리고Authenticator, JVM은 셸 변수를 읽지 않기 때문입니다. - 브라우저 — 캐시된 407은 자격 증명을 수정한 후에도 지속될 수 있습니다; 수정이 실패했다고 가정하기 전에 강제 새로고침하거나 캐시를 지우세요.
- Docker — 데몬과 빌드 모두 프록시 설정이 필요하며, 서로 다른 위치에 구성됩니다.
이 모든 파일을 편집하는 동안 보안 주의 사항 하나: 글로벌 git 또는 npm 구성에 있는 자격 증명은 평문으로 끝나며, 비밀번호가 포함된 프록시 URL은 셸 기록, CI 로그 및 오류 추적에 누출됩니다. 안정적인 주소가 있는 머신에서는 IP 화이트리스트를 사용하여 비밀을 완전히 피할 수 있습니다.

407은 절대 대상 사이트의 잘못이 아닙니다
이것은 유령을 쫓는 것을 피할 수 있기 때문에 재차 강조할 가치가 있습니다. 407을 받고 있다면, 사용자 에이전트를 회전시키거나, 헤더를 추가하거나, 종료 국가를 변경하는 것은 도움이 되지 않습니다 — 요청은 아직 프록시를 떠나지 않았습니다. 대상에서 오는 차단은 다르게 보입니다: 403 Forbidden은 사이트가 당신을 거부했다는 것을 의미하고, 429 Too Many Requests는 너무 빠르게 요청했다는 것을 의미합니다. 어떤 세 가지 중 하나인지 진단한 후에 코드를 작성하세요. 그리고 Python이 ProxyError나 SSLError를 던지고 깨끗한 407이 아니라면, 우리의 Requests에서 ProxyError 디버깅 가이드는 전송 수준의 실패를 다룹니다.
자주 묻는 질문
407 Proxy Authentication Required를 어떻게 해결하나요?
유효한 자격 증명을 http://user:pass@host:port 형식으로 프록시 URL에 넣고, 예약된 문자를 퍼센트 인코딩하며, HTTP 및 HTTPS 프록시 설정을 모두 구성하세요. 제공자가 대신 IP 화이트리스트를 사용하는 경우, 현재 공용 IP를 승인하고 자격 증명을 보내지 마세요. 애플리케이션 코드를 건드리기 전에 IP 에코 서비스에 대해 curl -x로 확인하세요.
407 Proxy Authentication Required는 무엇을 의미하나요?
이는 중간 프록시가 유효한 프록시 자격 증명이 부족하여 요청을 거부했음을 의미합니다. 응답에는 스킴을 명명하는 Proxy-Authenticate 헤더가 포함되며, 클라이언트는 Proxy-Authorization으로 재시도해야 합니다. 이는 중간 프록시가 아닌 대상 서버에서 오는 401과는 다릅니다.
npm 오류 407을 어떻게 수정하나요?
두 키를 모두 설정하세요: npm config set proxy와 npm config set https-proxy, 각각 전체 http://user:pass@host:port URL로. 레지스트리 트래픽은 HTTPS이므로, HTTP 전용 설정은 CONNECT 터널에서 실패합니다. 비밀번호의 특수 문자를 퍼센트 인코딩하고, 프로젝트 수준의 .npmrc가 글로벌 설정을 덮어쓰고 있는지 확인하세요.
Python이 왜 Tunnel connection failed: 407을 발생시키나요?
HTTPS 요청이 프록시 자격 증명이 없는 CONNECT 터널을 열었기 때문입니다. proxies dict의 http와 https 키를 동일한 인증된 URL로 설정하세요. 또한 환경에서 HTTP_PROXY 또는 HTTPS_PROXY가 dict를 덮어쓰고 있는지 확인하세요 — session.trust_env = False를 설정하여 이를 배제하세요.
Postman에서 프록시 인증을 어떻게 설정하나요?
설정을 열고, 프록시 탭으로 이동하여 사용자 정의 프록시 구성을 활성화하고, 호스트와 포트를 입력한 다음 프록시 인증 상자를 선택하고 사용자 이름과 비밀번호를 추가하세요. 시스템 프록시 토글에 의존하는 것이 일반적인 실수입니다 — 이는 프록시를 통해 트래픽을 라우팅하지만 자격 증명을 제공하지 않으므로 모든 요청이 407을 반환합니다.
다섯 가지 원인이 실제로 모든 407을 포괄합니다: 누락된 자격 증명, 인코딩되지 않은 특수 문자, 변경된 화이트리스트 IP, 인증되지 않은 CONNECT 터널, 자체 구성을 가진 도구. 그 순서대로 작업하면 상태 코드가 사라집니다 — 그런 다음 대상 사이트가 당신을 어떻게 생각하는지 걱정할 수 있습니다.