문제 해결 예상 읽기 시간 12분

Clash 로그가 어렵다면? 자주 나오는 오류 메시지의 의미와 문제 해결 방법

Clash 로그 레벨과 필드 의미를 설명하고 dial tcp timeout, connection refused, DNS 조회 실패, 규칙 미일치 등 자주 발생하는 오류의 원인과 구독·규칙·네트워크별 진단 방법을 정리합니다.

먼저 로그가 어느 단계에서 발생했는지 확인하기

Clash, Clash Meta, mihomo의 로그는 비슷해 보이지만 한 화면에 클라이언트 로그, 코어 로그, 설정 업데이트 기록이 함께 표시될 수 있습니다. 문제를 진단하기 전에 오류를 발생시킨 주체부터 확인하세요. 클라이언트는 구독 다운로드, 설정 저장, 코어 실행을 담당하고, 코어는 DNS, 규칙 매칭, 프록시 연결, TUN 트래픽 처리를 담당합니다. 구독 다운로드에 실패했다면 프록시 규칙을 바꿔도 해결되지 않으며, 코어가 실행되지 않았다면 노드 지연 시간 테스트도 의미 있는 결과를 내지 못합니다.

세 가지 기록에서 확인할 내용

클라이언트마다 메뉴 이름은 조금씩 다릅니다. 일반적으로 「설정」→「로그」 또는 「코어」→「로그」에서 실시간 기록을 열 수 있으며, 일부 데스크톱 클라이언트는 「홈」→「로그」에 진입점이 있습니다. mihomo 그래픽 클라이언트는 보통 「설정」→「매개변수 설정」에서 로그 레벨도 조정할 수 있습니다. 문제를 재현할 때는 로그 화면을 열어 둔 상태에서 이전 기록을 지운 뒤 실패 작업을 한 번만 실행하세요. 이렇게 얻은 로그가 가장 읽기 쉽습니다.

레벨·연결 방향·규칙 결과 읽기

일반적인 로그 레벨에는 debug, info, warning, error가 있습니다. info는 정상 연결도 기록하므로 오류를 뜻하지 않습니다. warning은 작업 실패, 대체 처리 또는 일시적인 이상을 의미하지만 코어는 대개 계속 실행됩니다. error는 우선적으로 확인할 가치가 큽니다. 규칙을 점검할 때는 일시적으로 debug를 사용하고, 완료 후에는 info로 되돌리세요. DNS와 연결 세부 정보가 로그에 계속 쌓이는 것을 막을 수 있습니다.

[INFO] [TCP] 127.0.0.1:53142 --> example.com:443
match DomainSuffix(example.com) using Proxy[HK-01]

[WARNING] [TCP] dial Proxy (match DomainSuffix/example.com)
127.0.0.1:53142 --> example.com:443 error: i/o timeout

첫 번째 줄은 로컬 프로세스가 임시 포트 53142에서 TCP 연결을 시작했고 대상이 example.com:443임을 보여 줍니다. 이어서 DOMAIN-SUFFIX 규칙과 매칭되어 Proxy라는 정책 그룹으로 전달되며, 대괄호 안의 HK-01은 해당 그룹에서 실제로 선택된 노드입니다. 두 번째 부분은 연결이 프록시 경로에 진입했지만 제한 시간 안에 완료되지 않았다는 뜻입니다. 따라서 먼저 “규칙이 매칭되지 않았다”는 가능성을 제외하고 노드, 상위 네트워크 또는 대상 사이트를 확인해야 합니다.

로그를 볼 때는 다음 순서로 나누어 확인하기

  1. 프로토콜이 TCP인지 UDP인지 확인하세요. 웹 HTTPS는 대부분 TCP 443을 사용하지만 QUIC을 통해 UDP 443을 사용할 수도 있습니다.
  2. 출발지 주소를 확인하세요. 127.0.0.1은 보통 시스템 프록시 또는 로컬 앱을 의미하며, TUN이 트래픽을 가로채는 경우 가상 네트워크 어댑터 주소가 표시될 수 있습니다.
  3. 대상이 도메인인지 IP인지 확인하세요. IP만 표시되는 경우 일부 도메인 규칙이 매칭에 참여할 수 없습니다.
  4. match 뒤에 표시된 규칙 유형과 규칙 내용을 확인하세요.
  5. using 뒤의 정책 그룹과 실제 노드를 확인해 연결이 최종적으로 어디로 향했는지 판단하세요.
  6. 마지막으로 error 내용을 읽고 연결 시간 초과, 연결 거부, 조회 실패, 인증 실패를 구분하세요.

dial tcp timeout: 제한 시간 안에 연결이 설정되지 않음

dial tcp은 코어가 TCP 연결을 설정하는 중임을 의미합니다. 뒤에 나오는 i/o timeout, connect: operation timed out, context deadline exceeded는 모두 “대기 시간이 제한을 초과했다”는 뜻이지만, 시간 초과가 발생한 위치는 서로 다를 수 있습니다. 프록시 서버 연결에 실패했을 수도 있고, 프록시 서버가 대상 사이트에 연결하지 못했을 수도 있습니다. 오류 앞에 표시된 노드 이름, 대상 주소, 연속 실패 범위를 함께 확인해야 합니다.

노드 하나에서만 시간 초과가 발생하는 경우

같은 정책 그룹에서 HK-01만 계속 시간 초과되고 SG-02로는 동일한 웹사이트가 정상적으로 열린다면, 문제는 노드 또는 노드 경로에 집중됩니다. 먼저 클라이언트에서 지연 시간 테스트를 한 번 실행한 뒤 실제 웹페이지로 확인하세요. 지연 시간 테스트 URL이 200을 반환해도 테스트 경로에 연결할 수 있다는 뜻일 뿐, 모든 대상에 접근할 수 있다는 의미는 아닙니다. 5초 이상 시간 초과가 3회 연속 발생하는 경우가 단 한 번의 800밀리초 지연보다 연결 불안정을 더 잘 보여 줍니다.

모든 노드에서 동시에 시간 초과가 발생하는 경우

[WARNING] dial tcp 203.0.113.20:443: i/o timeout
[WARNING] dial tcp: lookup node.example.net: i/o timeout

이 두 줄은 같은 방식으로 처리하면 안 됩니다. 첫 번째 줄은 이미 서버 IP를 얻었으므로 TCP 연결 단계에서 시간 초과가 발생한 것입니다. 두 번째 줄은 아직 도메인 조회 단계에 머물러 있습니다. 전자는 서버 포트와 네트워크 경로를, 후자는 DNS 서버, DNS 라우팅, 로컬 네트워크를 확인하세요.

connection refused: 대상이 연결을 명확히 거부함

connection refused는 시간 초과와 다릅니다. 시간 초과는 유효한 응답을 오랫동안 받지 못했다는 뜻이고, 연결 거부는 대상 호스트가 빠르게 거부 결과를 반환했다는 뜻입니다. 포트에서 서비스가 수신 대기 중이지 않거나, 서비스가 중지되었거나, 포트를 잘못 입력했거나, 로컬 앱이 실행되지 않은 Clash 수신 포트에 연결한 경우가 흔한 원인입니다.

dial tcp 127.0.0.1:7890: connect: connection refused
dial tcp 198.51.100.8:8443: connect: connection refused

첫 번째 줄의 대상은 127.0.0.1:7890입니다. 어떤 앱이 로컬 프록시 포트에 연결을 시도했지만 해당 포트를 수신 중인 프로세스가 없다는 뜻입니다. 클라이언트 코어 상태를 확인하고 앱의 프록시 주소가 Clash 설정과 일치하는지 확인하세요. 일반적인 혼합 프록시 포트는 7890이지만 사용자 설정에 따라 7897, 7899 또는 다른 값일 수 있으므로 기본값만 보고 입력해서는 안 됩니다.

두 번째 줄은 원격 주소가 연결을 거부했다는 뜻입니다. 노드 서버에 해당한다면 노드 포트, 프로토콜 유형, 구독 업데이트 시점을 확인하세요. VMess 노드의 포트를 Trojan 설정에 잘못 입력했거나 서버가 포트를 변경했는데 이전 구독을 계속 사용하면 즉시 거부될 수 있습니다. 이 경우 오류는 프록시 서버 연결 단계에서 발생했으므로 규칙 모드를 반복해서 바꿔도 해결되지 않습니다.

DNS 조회 실패: 먼저 요청을 누가 처리하는지 확인하기

DNS 문제는 웹페이지에 서버를 찾을 수 없다는 메시지가 표시되고 로그에 lookup, no such host, all DNS requests failed, could not resolve 또는 상위 DNS 시간 초과가 나타나는 형태로 드러나는 경우가 많습니다. 핵심은 DNS 요청이 운영체제, Clash DNS 모듈, 브라우저 자체의 보안 DNS 중 어디로 향하는지 확인하는 것입니다. 세 경로가 동시에 사용되면 그중 하나를 바꿔도 실제 요청에 영향을 주지 않을 수 있습니다.

코어 DNS 설정 확인하기

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: fake-ip
  nameserver:
    - 223.5.5.5
  fallback:
    - tls://1.1.1.1:853

이 설정은 코어가 1053 포트에서 DNS 요청을 수신하도록 하며, 요청이 시스템의 53번 포트에 자동으로 나타나지는 않습니다. 그래픽 클라이언트는 보통 TUN 또는 DNS 가로채기를 활성화할 때 관련 라우팅을 추가합니다. 설정만 복사하고 시스템 DNS가 코어를 가리키도록 하지 않으면 앱은 계속 기존 리졸버를 사용할 수 있습니다. 반대로 해당 포트를 다른 프로그램이 이미 사용 중이면 실행 로그에 bind: address already in use가 표시됩니다.

증상에 따라 해결 방향 나누기

DNS를 변경한 뒤에는 기존 캐시를 삭제하고 다시 테스트하세요. Windows에서는 네트워크를 다시 연결하거나 터미널에서 ipconfig /flushdns를 실행할 수 있습니다. macOS에서는 네트워크 인터페이스를 껐다가 다시 켜세요. 브라우저에도 자체 DNS 및 연결 캐시가 남아 있을 수 있으므로 브라우저를 완전히 종료한 뒤 재테스트하는 편이 더 정확합니다.

규칙 미일치: 로그에 error가 없을 수도 있음

규칙 분기 오류는 빨간색 오류 메시지를 남기지 않는 경우가 많습니다. 연결은 성공했지만 DIRECT, 잘못된 노드 또는 최종 MATCH로 처리되면 사용자는 “규칙이 작동하지 않는다”고 느낄 수 있습니다. Clash와 mihomo는 설정 순서대로 위에서 아래로 확인하며 첫 번째로 매칭된 규칙에서 멈춥니다. 범위가 넓은 규칙을 앞에 두면 뒤의 정밀한 규칙이 가려집니다.

rules:
  - DOMAIN-SUFFIX,example.com,DIRECT
  - DOMAIN,api.example.com,Proxy
  - MATCH,Proxy

api.example.com에 접속할 때 첫 번째 DOMAIN-SUFFIX 규칙이 이미 매칭되므로 두 번째 정확한 도메인 규칙은 실행되지 않습니다. API를 프록시로 보내려면 DOMAIN,api.example.com,Proxy를 더 앞쪽으로 옮기세요. 로그에 match DomainSuffix(example.com) using DIRECT가 표시된다면 규칙 시스템은 정상적으로 작동하는 것이며, 문제는 코어가 설정을 무시한 것이 아니라 규칙 순서에 있습니다.

로그에 IP만 표시될 때 확인하는 방법

대상이 142.250.0.1:443과 같은 IP로 표시되면 DOMAINDOMAIN-SUFFIX 규칙에 사용할 도메인이 없을 수 있습니다. 앱이 IP에 직접 연결하거나, DNS 매핑이 연결과 연동되지 않았거나, 트래픽이 코어를 완전히 거치지 않은 것이 원인일 수 있습니다. IP-CIDR, GEOIP 또는 최종 MATCH에 매칭되었는지 확인하세요. no-resolve가 적용된 IP 규칙은 매칭을 위해 도메인을 추가로 조회하지 않으며, 해당 규칙을 건너뛴다는 뜻이 아닙니다.

규칙 세트 로드 실패

원격 규칙 세트를 다운로드하지 못하면 로그에 HTTP 404, context deadline exceeded 또는 provider update failed가 표시될 수 있습니다. 먼저 규칙 세트 URL과 업데이트 시점을 확인한 다음 다운로드 요청에 사용된 정책을 확인하세요. 규칙 세트를 처음 불러올 때 실패하면 해당 규칙 세트에 의존하는 규칙을 사용할 수 없게 될 수 있습니다. 캐시가 있다면 코어가 이전 버전을 계속 사용할 수도 있습니다. 문제가 시작 단계에서 발생했는지 정기 업데이트 단계에서 발생했는지도 기록해야 합니다.

구독·설정·코어 실행 오류

로그에 TCP 또는 UDP 연결 기록이 전혀 없다면 먼저 코어가 설정을 성공적으로 로드했는지 확인하세요. YAML 들여쓰기 오류, 존재하지 않는 노드를 참조하는 정책 그룹, 포트 충돌, 호환되지 않는 설정 필드 때문에 코어가 트래픽을 인계하기 전에 종료될 수 있습니다.

HTTP 상태 코드별 구독 문제

로그 상태 일반적인 의미 우선 확인할 항목
401 Unauthorized 유효한 인증 정보가 포함되지 않은 요청 구독 토큰이 완전한지, 링크가 잘리지 않았는지 확인
403 Forbidden 서버가 요청을 받았지만 콘텐츠 제공을 거부함 구독 상태, 접근 제한, 요청 출처
404 Not Found 구독 경로가 존재하지 않음 링크가 만료되지 않았는지, 경로를 잘못 복사하지 않았는지 확인
429 Too Many Requests 짧은 시간에 요청이 너무 많이 발생함 자동 새로고침을 중지하고 제한이 해제될 때까지 기다리기
5xx 구독 서비스 서버의 일시적인 오류 잠시 후 다시 시도하고 현재 사용 가능한 설정은 보존하기

YAML 및 참조 오류

yaml: line 42: did not find expected key
proxy group Proxy: proxy HK-01 not found
listen tcp 127.0.0.1:7890: bind: address already in use

Clash Premium, Clash Meta, mihomo가 지원하는 설정 필드는 완전히 동일하지 않습니다. 최신 mihomo에서 생성한 설정을 구형 코어로 로드하면 unknown field 또는 파싱 오류가 발생할 수 있습니다. 먼저 클라이언트의 「정보」 또는 「코어」 페이지에서 실제 코어 이름과 버전을 확인한 뒤 해당 코어가 지원하는 필드와 대조하세요. 클라이언트 외형의 버전만 확인해서는 안 됩니다.

재현 가능한 로그 문제 해결 절차

  1. 증상 기록: 실패 시각, 앱 이름, 대상 도메인, 시스템 프록시 또는 TUN 활성화 여부를 적어 두세요.
  2. 코어 상태 확인: 코어 실행 여부, mixed-port 수신 여부, 실행 로그의 설정 오류를 확인하세요.
  3. 로그 지우기: 레벨을 info로 설정하고 이전 기록을 삭제해 오래된 오류가 판단을 방해하지 않도록 하세요.
  4. 한 번만 재현: 실패한 페이지를 한 번 열거나, 구독을 한 번 새로고침하거나, 노드 연결을 한 번 실행하세요. 여러 앱을 동시에 조작하지 마세요.
  5. 대상부터 찾기: 도메인, IP 또는 구독 주소를 검색한 뒤 앞뒤 10~20줄의 문맥을 확인하세요.
  6. 단계 구분: 구독 HTTP 오류는 구독 단계, YAML 및 포트 오류는 실행 단계, lookup은 DNS, match는 규칙, dial은 연결 단계로 분류하세요.
  7. 단일 변수 테스트: 한 번에 노드 하나, DNS 상위 서버 하나 또는 인계 모드 하나만 변경하세요. 변경할 때마다 로그를 다시 지우세요.
  8. 로그 레벨 복원: 문제를 해결한 뒤 debug를 info로 되돌려 불필요한 기록을 줄이세요.

예를 들어 어떤 웹사이트가 TUN 모드에서는 8초 후 실패하지만 시스템 프록시 모드에서는 1.2초 안에 열릴 수 있습니다. 로그를 보면 두 모드 모두 같은 노드에 매칭되지만 시스템 프록시 모드에서는 TCP 연결이 완료되고 TUN 모드에는 해당 대상 기록이 없습니다. 이 경우 노드와 규칙은 거의 원인에서 제외되므로 TUN 라우팅, 앱의 가상 네트워크 어댑터 사용 여부, DNS 가로채기, 시스템 권한을 중점적으로 확인해야 합니다. 이런 비교 테스트가 노드를 열 개씩 바꿔 보는 것보다 훨씬 효과적입니다.

다른 사람에게 로그를 제공하기 전에는 시간, 오류 유형, 대상 포트, 규칙 유형, 정책 그룹 이름은 남겨도 됩니다. 대신 구독 토큰, 인증 필드, 전체 노드 주소, 로컬 사용자 이름은 삭제하거나 가리세요. 마지막 error 한 줄만 캡처하지 말고, 최소한 오류 전후의 실행 정보나 연결 문맥을 포함해야 시간 초과가 DNS, 노드, 대상 사이트 중 어디에서 발생했는지 판단할 수 있습니다.

Clash 클라이언트 다운로드 Windows, macOS 및 모바일 버전 확인