ChatGPT 웹은 정상인데 Codex가 느린가요? 프록시, 재연결, TLS 오류 점검
ChatGPT 웹에서는 정상적으로 대화되고 Google도 빠른데 Codex 응답이 늦거나 Reconnecting이 반복될 수 있습니다. 이런 경우 먼저 Codex 연결 오류를 확인하고 경로 변경, 프록시 조정, 모델 응답 대기 중 무엇이 필요한지 판단하세요.
웹사이트가 작동한다는 사실은 현재 브라우저 경로가 사용 가능하다는 것만 보여 줍니다. Codex 요청도 같은 프록시를 사용하거나 Codex의 지속 연결이 정상이라는 뜻은 아닙니다. 로그에 이미 tls handshake eof, 연결 재설정 또는 반복 재연결이 있다면 대기 시간을 전부 모델 추론 탓으로 볼 수 없습니다.
이 글은 연결 이상이 동반된 Codex 지연을 다룹니다. 점검 순서는 재연결 중인지 확인 → 실제 프록시 경로 확인 → TLS와 일반 HTTPS 점검 → 그다음 WebSocket 또는 스트리밍 연결 검증입니다.
아래 판단은 Mac에서 수행한 한 번의 실험을 바탕으로 합니다. Tailscale에서는 실제 Codex 호출 세 건이 완료됐고, 저장된 AnyTLS 노드를 격리 환경에서 다시 구성하자 TLS EOF가 발생했으며 Google HTTPS에도 연결하지 못했습니다. 이 실험은 이전의 “웹은 빠른데 Codex만 느림” 상태를 완전히 재현하지 못했으므로 과거 장애의 유일한 근본 원인으로 볼 수 없습니다. 서로 다른 증거가 나왔을 때 어느 계층을 먼저 확인할지 판단하는 데 활용할 수 있습니다.
Codex가 생각 중인가요, 아니면 계속 재연결 중인가요?
화면에 얼마나 오래 표시됐는지만 보지 말고 현재 요청에 해당하는 오류를 먼저 찾으세요.
| 표시된 현상 또는 오류 | 먼저 확인할 항목 |
|---|---|
Reconnecting...와 tls handshake eof가 함께 표시됨 |
프록시 경로, TLS 연결 설정, 대상 전달 |
stream disconnected before completion |
뒤따르는 구체적인 오류 확인. 이 문구만으로는 원인을 알 수 없음 |
| WebSocket 연결 후 끊김, 종료 코드 1006 | 해당 연결의 종료 시점과 지속 시간, 중간 네트워크 경로 |
| 모델에 업데이트 버전이 필요하다고 명시된 HTTP 400 | 클라이언트 버전. 우선 네트워크 문제로 분류하지 말 것 |
| 연결 오류 없이 결과만 오래 기다림 | 원인을 단정하지 말 것. 느리다는 사실만으로 네트워크 단절을 판단할 수 없음 |
이번 실험에서는 같은 모델과 추론 수준을 사용하고 Codex에 고정 문자열 NETWORK_PROBE_OK를 반환하도록 요청했습니다.
| 경로 | 실제 호출 결과 |
|---|---|
| Tailscale, 독립된 짧은 세션 세 번 | 모두 완료. 전체 CLI 프로세스 시간은 11.551, 13.945, 14.877초 |
| 로컬 HTTP CONNECT, Tailscale을 통한 외부 연결 | 완료. 전체 프로세스 시간 11.634초 |
| 로컬 HTTP CONNECT, 저장된 AnyTLS 노드 사용 | 재연결 반복, 45초 관찰 시간 안에 완료되지 않음 |
실패한 호출에는 다음 로그가 나타났습니다.
Reconnecting... 2/5 (... tls handshake eof)
Reconnecting... 3/5 (... tls handshake eof)
Reconnecting... 4/5 (... tls handshake eof)
Reconnecting... 5/5 (... tls handshake eof)
Reconnecting... waiting for network
이 상황에서 계속 기다린다고 모델이 답변을 꾸준히 생성하는 것은 아닙니다. 요청이 연결에 실패해 재시도 중이므로 연결부터 점검하세요.
표의 시간에는 프로세스 시작, 인증, 추론, 전송이 포함됩니다. 첫 토큰까지의 시간도 순수 네트워크 시간도 아닙니다. 45초는 테스트 프로그램의 종료 한도이지 프록시 평균 응답 시간이 아닙니다.
ChatGPT 웹은 정상인데 Codex는 왜 연결하지 못할까요?
브라우저, 데스크톱 앱, CLI의 실제 연결 경로를 각각 확인하세요. 브라우저 프록시 확장, 시스템 프록시, TUN, 프로세스별 라우팅, 터미널 프록시 환경 변수는 서로 다른 범위에 적용될 수 있습니다. 한 프로그램이 작동한다고 다른 프로그램도 같은 경로를 이용하는 것은 아닙니다.
Clash Verge에서는 먼저 다음 세 가지를 확인하세요.
- Codex가 요청을 보낼 때 Clash 연결 기록에 해당 트래픽이 나타나나요? 터미널에 변수를 설정한 것만으로 요청이 프록시를 통과했다고 확인할 수 없습니다.
- 요청이 예상한 규칙과 출구 경로에 매칭됐나요? 노드 선택 화면만 보지 말고 현재 요청을 확인하세요.
- 같은 사용 환경끼리 비교하나요? CLI 테스트 성공이 데스크톱 백그라운드 연결 전부의 성공을 뜻하지 않습니다. 웹에서 대화할 수 있다는 사실도 데스크톱 연결 테스트를 대신하지 않습니다.
이번 실제 CLI 프록시 테스트에서는 격리된 프록시 연결 기록에 chatgpt.com이 나타나 요청이 해당 프록시 입구에 도달했음을 확인했습니다. 별도로 수행한 HTTP CONNECT 양성 대조에서는 실제 요청이 완료되어 이번 실험에서 이 클라이언트가 해당 입구를 통해 작동할 수 있음을 보여 줬습니다.
하지만 데스크톱 로그에서 오류가 보고된 durable/app-server 채널은 별도로 분석해야 합니다. OpenAI 문서도 SSE, WebSocket 요청과 이벤트를 별도의 관측 범주로 나눕니다. 서로 다른 채널의 성공과 실패를 합쳐 “Codex 네트워크가 정상”이라고 결론 내릴 수 없습니다.Codex 연결 텔레메트리 이벤트 범주
브라우저는 정상인데 해당 Codex 트래픽이 예상한 프록시에 나타나지 않는다면 먼저 그 요청의 경로를 바로잡으세요. 노드를 계속 바꿔도 문제가 있는 연결 경로가 바뀌지 않을 수 있습니다.
Codex에서 tls handshake eof가 나오면 무엇부터 확인하나요?
tls handshake eof는 TLS 핸드셰이크 도중 조기에 종료됐다는 의미입니다. “WebSocket이 정상 연결된 뒤 유휴 상태에서 시간 초과됐다”는 뜻이 아닙니다. 먼저 같은 프록시를 통한 일반 HTTPS가 가능한지 확인한 다음 애플리케이션 지속 연결을 조사하세요.
같은 프록시에서 일반 HTTPS가 되는지 확인
간단한 HTTPS 주소를 현재 시스템 네트워크 경로와 명시적으로 지정한 로컬 프록시 경로에서 각각 테스트하세요. 실행 중인 클라이언트의 포트를 사용해야 합니다. 브라우저에서 같은 URL을 시험하는 것만으로는 Codex 경로를 확인할 수 없습니다.
아래는 포트를 바꿔 사용할 수 있는 명령 예시입니다. 7897은 예시 값이므로 현재 Clash HTTP 또는 mixed 포트로 바꾸세요. 이번 실험은 스크립트가 할당한 임시 포트를 사용했습니다.
# 不显式使用 HTTP 代理,沿当前系统路由访问。
# 如果开着 TUN 或 Tailscale,这不等于绕过它们。
curl --noproxy '*' --connect-timeout 10 --max-time 25 \
-o /dev/null -sS -w 'HTTP=%{http_code} total=%{time_total}s\n' \
https://www.google.com/generate_204
# 明确经过本地 HTTP/mixed 代理入口。
curl --proxy http://127.0.0.1:7897 --noproxy '' \
--connect-timeout 10 --max-time 25 \
-o /dev/null -sS -w 'HTTP=%{http_code} total=%{time_total}s\n' \
https://www.google.com/generate_204
로컬 포트에 연결할 수 없다면 먼저 Clash 실행 여부와 포트가 맞는지 확인하세요. 아직 원격 노드를 테스트한 것이 아닙니다. TLS 단계에서만 실패한다면 노드와 대상 전달을 점검하세요. 두 명령이 모두 성공해도 짧은 HTTPS가 된다는 것만 확인한 것이므로 Codex도 계속 테스트해야 합니다.
이번 실험은 대상별로 각 경로를 세 번씩 테스트했습니다.
| 테스트 대상 | Tailscale 경로 | 저장 노드의 격리 프록시 경로 |
|---|---|---|
Google generate_204 |
세 번 모두 HTTP 204 | 세 번 모두 curl 35, HTTP 응답 없음 |
| ChatGPT 홈페이지 | 세 번 모두 HTTP 403 | 세 번 모두 curl 35, HTTP 응답 없음 |
| Codex responses 주소의 인증되지 않은 GET | 세 번 모두 HTTP 405 | 세 번 모두 curl 35, HTTP 응답 없음 |
curl 35는 SSL/TLS 연결 오류이며 이번 메시지는 SSL_ERROR_SYSCALL이었습니다.curl 오류 코드 설명
403과 405는 ChatGPT 또는 Codex 기능이 정상이라는 뜻이 아닙니다. 프로브가 HTTP 응답을 받았다는 것만 의미합니다. 인증되지 않은 GET은 정식 모델 호출을 대신할 수도 없습니다. 실제 애플리케이션 확인은 앞 절에서 고정 표식을 반환한 요청입니다.
그래도 프록시 경로에서 Google HTTPS까지 실패했으므로 점검 순서를 바꿔야 합니다. Codex WebSocket을 원인으로 먼저 단정하지 말고 일반 HTTPS 전달부터 복구하세요.
노드에 연결돼도 OpenAI 연결을 대신할 수 있다는 뜻은 아닙니다
프록시 입구에 연결할 수 있더라도 인증, 프로토콜 호환성, 대상 전달을 확인해야 합니다.
이번 실험에서는 프록시 클라이언트를 우회하고 네이티브 소켓을 물리 네트워크 인터페이스에 바인딩해 노드가 해석한 IPv4 입구 네 곳에 연결했습니다. 네 곳 모두 TCP 연결에 성공했고 약 4–7 ms가 걸렸습니다. 인증서 검증을 포함한 TLS 핸드셰이크도 모두 성공했으며 전체 시간은 약 248–553 ms였습니다.
이는 입구에 도달할 수 있다는 것만 보여 줍니다. 프록시 경로에는 다음 단계가 더 있습니다.
本机 → 代理入口 TCP/TLS → 认证、协议处理与转发 → 目标服务
입구까지 TLS 성공과 프록시를 통해 대상에 TLS 성공은 별개의 검증입니다. 전자는 AnyTLS 인증이나 노드가 Google 또는 OpenAI에 연결할 수 있음을 증명하지 않습니다.
이번 실험에서는 노드 호스트명을 해석된 IP 하나로 고정해도 Google HTTPS가 실패했습니다. 같은 구현의 로컬 HTTP CONNECT 입구를 DIRECT로 바꾸고 Tailscale을 통해 외부로 연결하자 Google 204가 반환됐습니다. 이 대조 결과는 노드 프로토콜과 클라이언트 호환성, 인증 및 전달 상태, 서버 측 외부 연결 기록에 주의를 기울이게 하지만 하나의 근본 원인을 확정하지는 않습니다.
결과가 같다면 “핑이 낮다” 또는 “서버 포트에 연결된다”로 조사를 끝내지 말고 해당 단계의 오류 기록을 확보하세요.
Codex가 계속 재연결하면 WebSocket을 꺼야 하나요?
먼저 Codex 앱이 사용하는 WebSocket과 프록시 노드의 전송 프로토콜을 구분하세요.
이번 저장된 선택 노드는 AnyTLS였고 설정에 있는 VLESS/WS 노드가 아니었습니다. 따라서 “노드가 WS로 감싸져 있어 Codex가 느리다”는 추정은 저장된 노드 유형과 맞지 않습니다. 다만 Codex 자체 WebSocket이 이 노드를 통과하는 동안 실패할 가능성은 있습니다.
WebSocket을 조사할지는 연결이 어디까지 진행됐는지에 따라 달라집니다.
| 확인된 증거 | 점검할 부분 |
|---|---|
| 일반 HTTPS도 TLS 핸드셰이크 완료 불가 | 먼저 프록시 연결 설정과 전달을 복구 |
| 일반 HTTPS는 정상이나 WS 핸드셰이크 실패 | 해당 연결의 핸드셰이크, 프록시 경로, 접근 정책 확인 |
| WS 연결 후 사용 중 또는 유휴 뒤 끊김 | 끊긴 시점을 기록하고 연결 유지 및 중간 경로 조사 |
이번에는 Postman 공개 WSS Echo 서비스로 지속 연결을 확인했습니다. Tailscale에서 메시지 다섯 개를 교환하고 테스트 클라이언트의 능동 주기 ping을 끈 뒤 90초 유휴 상태로 두었다가 다섯 개를 더 교환했습니다. 열 개의 에코가 모두 일치했습니다. 능동 ping을 끄더라도 TCP keepalive나 서버가 보낼 수 있는 프레임이 제거되는 것은 아닙니다.Postman Echo 서비스 안내
별도의 HTTP CONNECT/DIRECT 양성 대조에서도 WSS 핸드셰이크와 에코가 성공했습니다. 이는 이 로컬 프록시 입구가 WSS를 전달할 수 있다는 뜻이지 모든 프록시 노드가 정상이라는 뜻은 아닙니다. 공개 Echo 서비스도 Codex의 특정 엔드포인트를 대신하지 않습니다.
과거 데스크톱 로그에서는 durable 채널과 관련된 websocket_error 10건과 reconnect_started 15건을 명확히 찾았습니다. 이는 이벤트 기록이지 독립 장애 25건을 뜻하지 않습니다. 한 오류가 여러 상태 로그로 전파될 수도 있습니다.
종료 코드 1006은 비정상 종료를 뜻하지만 그것만으로 누가 연결을 끊었는지 판단할 수 없습니다.WebSocket 비정상 종료 코드의 RFC 정의
따라서 Reconnecting이 보인다고 “WS 끄기” 설정을 바로 적용하지 마세요. 이번 실패는 TLS 단계부터 나타났으며 WebSocket 유휴 시간 초과를 변경하면 해결된다는 증거는 없습니다.
Tailscale로 바꾸면 Codex 지연이 해결되나요?
이 Mac에서 이번 짧은 요청 테스트를 할 때 Tailscale은 실제 호출이 완료된 경로였습니다. 언제나 더 빠르다는 보장은 아닙니다. Codex 실제 호출 세 건과 90초 유휴 에코는 단순 속도 측정보다 지금 어떤 경로를 사용할지 판단하는 데 도움이 됩니다.
Tailscale은 WireGuard를 사용합니다. 직접 연결할 수 있으면 UDP로 전송하고 직접 연결이 안 되면 릴레이를 쓸 수 있습니다. Codex WebSocket은 터널 안에서 작동할 수 있으므로 Tailscale로 바꿔도 WebSocket이 꺼지는 것은 아닙니다.Tailscale 연결 방식
이번 Tailscale 발견 프로브 20회 중 17회가 성공하고 세 번 시간 초과됐습니다. 성공한 표본의 RTT 중앙값은 188 ms였습니다. 이것을 애플리케이션 트래픽의 장기 패킷 손실률로 볼 수는 없지만 “작동함”이 “지연과 이상이 전혀 없음”을 뜻하지도 않습니다.
마찬가지로 dig만으로 163 백본망 혼잡을 증명할 수 없습니다. 이번 ChatGPT 도메인의 A 레코드 조회는 세 번 모두 성공했고 185–233 ms가 걸렸습니다. 이 시간은 DNS 조회 측정이며 TCP, TLS, 실제 애플리케이션 요청을 대신하지 않습니다. 이번 실험은 163 백본망 혼잡을 확인하기에 충분한 경로 증거를 얻지 못했습니다.
출구 경로를 바꾼 뒤 Codex가 복구됐다면 확인되는 것은 “경로를 바꿔 결과가 달라졌다”는 사실입니다. 특정 통신사, 공유 노드 부하, 프록시 프로토콜에 원인을 돌리려면 그 판단을 뒷받침하는 증거가 더 필요합니다.
웹사이트가 열린 것 말고 Codex가 복구됐는지 어떻게 확인하나요?
브라우저 홈을 새로 고치는 것만으로는 부족합니다. 문제가 발생한 클라이언트 안에서 확인하세요.
- 도구를 호출하지 않는 짧은 요청을 보냅니다. 같은 모델과 추론 수준을 유지하고 완전한 결과가 돌아오는지 확인해 도구 실행 시간이 연결 확인에 섞이지 않게 합니다.
- 해당 요청의 프록시 규칙, 출구, 오류 기록을 확인합니다. 재연결이 계속되는지 보세요. 프록시를 설정했다는 것만으로 요청이 실제 통과했음을 입증하지 않습니다.
- 원래 실패했던 작업 흐름도 확인합니다. 짧은 요청 성공은 긴 작업, 유휴 후 복구, 데스크톱 백그라운드 채널 검증을 대신하지 않습니다. 이번 실험에서는 짧은 모델 요청만 완료했으며 긴 작업 흐름이 복구됐음을 증명하지 못했습니다.
데스크톱 앱에서는 “파일을 읽거나 도구를 호출하지 말고 NETWORK_PROBE_OK만 답해”라고 보냅니다. CLI 사용자는 아래 짧은 요청 예시를 참고할 수 있습니다. 실제 모델을 호출하며 오프라인 검사가 아닙니다.
codex exec --ephemeral --skip-git-repo-check --sandbox read-only \
'不要读取文件或调用工具,只回复 NETWORK_PROBE_OK'
실제로 문제가 있었던 버전과 설정에서 확인하고 오류와 완료 상태를 기록하세요. 다른 CLI가 응답한다고 데스크톱 앱도 복구됐다고 선언하지 마세요.
클라이언트가 모델에 더 새로운 버전이 필요하다고 명시하면 버전 호환성을 먼저 해결하세요. 이번 첫 테스트에서도 이런 상황이 발생했습니다. 독립 CLI 0.151.0은 HTTP 400을 반환했고 이후 앱에 포함된 0.164.0-alpha.11.1로 다시 테스트했습니다. 첫 HTTP 400은 네트워크 실패로 계산하지 않았습니다.
이번 결과를 바탕으로 한 실용적인 선택은 실제 호출이 완료된 Tailscale을 계속 사용하는 것입니다. 이 프록시를 조사할 때는 Codex의 특정 연결을 검증하기 전에 일반 HTTPS를 복구하세요. 이전의 “웹은 정상인데 Codex만 느림” 문제를 설명하려면 그 상태가 재현될 때 연결과 출구 기록을 동시에 수집해야 합니다.
테스트 범위: 이 글의 데이터는 2026년 10월 27일 새벽 Mac에서 수행한 테스트에서 나왔습니다. 프록시 실험은 저장된 AnyTLS 노드 매개변수를 읽고 별도 mihomo 프로세스에서 재구성했습니다. 원래 Clash GUI/TUN을 시작하거나 시스템 프록시 또는 Tailscale 출구를 변경하지 않았습니다. 물리 인터페이스 바인딩을 설정했지만 nettop에서 AnyTLS 프로세스의 확인 가능한 상위 인터페이스를 포착하지 못했으므로 두 전체 물리 경로를 완전히 독립 검증했다고 말할 수 없습니다. CLI, 데스크톱 durable 채널, 공개 Echo 결과는 각각 기록했습니다. 원시 데이터, 스크립트, 세부 조건은 함께 제공된 실험 자료에 보관되어 있습니다.
작성자:AIRouter
링크:https://www.airouter.me/blog/codex-slow-chatgpt-works
비영리 출처 표기 시 전재 가능(CC BY-NC-SA 4.0).