먼저 문제가 발생한 계층을 확인하세요
Clash 클라이언트가 구독을 업데이트할 때는 일반적으로 도메인 확인, TCP 및 TLS 연결, HTTP 요청 전송, 응답 수신, 구독 형식 확인, YAML 또는 노드 URI 파싱을 차례로 수행한 뒤 mihomo 같은 코어에 결과를 전달해 로드합니다. 화면에 같은 “업데이트 실패”가 표시되어도 실제로는 전혀 다른 단계의 문제일 수 있습니다. 업데이트 버튼을 반복해서 누르는 것만으로는 같은 오류가 되풀이될 뿐입니다.
점검을 시작하기 전에 오류 원문, 발생 시각, 클라이언트가 현재 사용하는 코어 버전을 기록하세요. 단순히 “작동하지 않음”이라고만 적지 마세요. timeout, 403 Forbidden, yaml: unmarshal errors, unexpected end of file 같은 키워드만으로도 네트워크, 접근 제어, 형식 파싱 중 어디에 가까운지 범위를 좁힐 수 있습니다.
| 화면에 나타나는 현상 | 우선 확인할 항목 | 일반적인 의미 |
|---|---|---|
| 링크를 붙여 넣자마자 형식 오류가 표시됨 | 링크 완전성 및 응답 내용 | 링크가 일부만 복사되었거나 서버가 웹페이지 또는 JSON 오류를 반환함 |
| 약 10~30초 후 시간 초과 | DNS, 라우팅, TLS, 로컬 네트워크 | 요청이 구독 서버에 안정적으로 도달하지 못함 |
| 업데이트 성공으로 표시되지만 노드 수가 0개 | 구독 유형, 요금제 상태, 콘텐츠 형식 | 응답은 읽을 수 있지만 현재 진입점에서 필요한 데이터가 아님 |
| 브라우저에서는 열리지만 클라이언트는 403을 반환함 | User-Agent, 요청 헤더, 요청 빈도 | 서버가 클라이언트 특성이나 요청 빈도에 따라 요청을 제한함 |
| 기존 설정은 작동하지만 새 구독을 불러오지 못함 | YAML 필드, 프록시 프로토콜, 코어 버전 | 새 콘텐츠에 현재 코어가 지원하지 않는 구조가 포함됨 |
첫 번째 단계: 구독 링크가 아직 유효한지 확인
복사한 결과와 HTTP 상태 확인
먼저 링크를 일반 텍스트 편집기에 붙여 넣고, 시작 부분이 https:// 또는 서비스 제공자가 명확히 안내한 http:// 주소인지 확인하세요. 메신저는 물음표, 등호, 하이픈 근처에서 링크를 잘라 버릴 수 있으며, QR 코드 인식 과정에서 공백이나 줄바꿈이 섞일 수도 있습니다. URL 끝에 token=, key= 같은 매개변수가 있다면 문자 하나만 빠져도 401, 403 또는 빈 응답이 반환될 수 있습니다.
터미널에서 응답 헤더만 확인할 수 있습니다. Windows 11에서는 “터미널”→“PowerShell”을 열고, macOS에서는 “응용 프로그램”→“유틸리티”→“터미널”을 여세요. 아래 명령의 주소는 현재 기기에서 직접 바꾸고, 실행 결과를 공개적으로 전달하지 마세요:
curl -I -L --connect-timeout 10 --max-time 30 "구독 주소"
-L은 301 또는 302 리디렉션을 따라가는 옵션이며, 연결 시간 제한은 10초, 전체 제한 시간은 30초로 설정합니다. 자주 보이는 상태 코드는 다음과 같이 해석할 수 있습니다:
- 200: 서버가 콘텐츠를 반환했지만, 그 콘텐츠가 유효한 구독이라고 단정할 수는 없습니다.
- 301, 302, 307, 308: 리디렉션이 있습니다. 클라이언트가 너무 오래되었거나 리디렉션 대상에 접근하지 못하면 실패할 수 있습니다.
- 401, 403: 토큰이 만료되었거나 계정 상태에 문제가 있거나, 요청 특성이 요구 조건에 맞지 않거나, 접근 출처가 제한된 상태입니다.
- 404, 410: API 경로가 변경되었거나 기존 구독 주소가 폐기되었습니다.
- 429: 짧은 시간에 업데이트 요청을 너무 많이 보냈습니다. 재시도를 중지하고 서버의 제한 시간이 끝날 때까지 기다리세요.
- 500, 502, 503, 504: 구독 서버 또는 상위 서버에 일시적인 문제가 있습니다. 일정 시간 후 다시 확인하세요.
브라우저에서 열린다고 클라이언트에서도 반드시 업데이트되는 것은 아닙니다
브라우저와 Clash 클라이언트는 서로 다른 DNS, 프록시 경로, Cookie, User-Agent, 리디렉션 처리 방식을 사용할 수 있습니다. 브라우저에서 파일이 다운로드된다는 것은 현재 브라우저 환경에서 접근할 수 있다는 뜻일 뿐입니다. 클라이언트는 요청 헤더 차이, 프록시 루프, 대상 도메인 확인 실패 때문에 여전히 오류가 발생할 수 있습니다.
계정 측 상태도 확인해야 합니다. 트래픽을 모두 사용했거나 요금제가 만료되었거나 구독 주소가 재설정된 경우, 일부 서비스는 명확한 401 대신 안내 문구나 HTML 로그인 페이지를 반환합니다. 클라이언트가 이런 콘텐츠를 받으면 표면적으로는 YAML 오류처럼 보이는 “파싱 실패”를 표시하지만, 실제 원인은 구독 권한 변경일 수 있습니다.
두 번째 단계: 응답 내용이 Clash에서 인식할 수 있는 형식인지 확인
전체 설정, 프록시 컬렉션, 범용 노드 목록 구분
일반적인 구독은 한 가지 구조로만 제공되지 않습니다. 전체 Clash 설정은 보통 YAML이며 proxies, proxy-groups, rules, dns 같은 최상위 필드를 포함할 수 있습니다. 프록시 컬렉션은 대개 proxy-providers에서 참조하며, 콘텐츠의 중심에 payload가 있을 수 있습니다. 또 다른 범용 구독은 Base64로 인코딩된 노드 URI 목록이며, 디코딩하면 ss://, trojan://, vmess:// 같은 항목을 볼 수 있습니다.
이 세 가지 콘텐츠는 용도가 서로 다릅니다. proxy-providers에서만 사용하는 컬렉션 주소를 전체 설정으로 가져오면 클라이언트가 프록시 그룹과 규칙이 없다고 표시할 수 있습니다. 반대로 전체 YAML을 노드 목록만 받는 변환 진입점에 넣으면 노드 수가 0개로 나올 수 있습니다. 먼저 서비스 제공자가 “Clash 설정”, “Mihomo 설정”, “프록시 컬렉션”, “범용 구독” 중 무엇으로 표시했는지 확인하세요.
최소한의 전체 구조는 대체로 다음과 비슷합니다. 실제 설정에는 포트, DNS, 더 많은 규칙이 포함되지만 들여쓰기 관계는 동일하게 유지되어야 합니다:
mixed-port: 7890
mode: rule
proxies:
- name: example-node
type: ss
server: 192.0.2.10
port: 443
cipher: aes-128-gcm
password: example-password
proxy-groups:
- name: PROXY
type: select
proxies:
- example-node
- DIRECT
rules:
- MATCH,PROXY
웹페이지, 오류 JSON, 잘린 파일 제외
아래 명령으로 응답 본문을 저장한 다음 텍스트 편집기에서 앞부분 수십 줄을 확인하세요. 파일 이름은 로컬 임시 이름을 사용하면 됩니다:
curl -L --connect-timeout 10 --max-time 30 \
-o subscription-response.txt \
"구독 주소"
시작 부분에 <!doctype html>, <html>, 로그인 양식 또는 CAPTCHA 안내가 나타나면 응답은 웹페이지입니다. 내용이 {"code":403,"message":"..."} 같은 구조라면 API 오류 JSON입니다. 파일 끝이 닫히지 않은 따옴표나 목록에서 갑자기 끝나거나 Base64 문자열 중간에서 끊겼다면 다운로드가 중단되었거나 서버가 콘텐츠를 완전히 생성하지 못했을 가능성이 있습니다.
- YAML 들여쓰기는 계층 구조를 표현하며, 목록 항목 앞의 하이픈은 올바른 계층에 있어야 합니다.
- Tab 문자는 YAML 스캔 오류를 일으킬 수 있으므로 설정 들여쓰기에는 공백을 사용해야 합니다.
- 노드 이름에 콜론, 해시, 중괄호 같은 문자가 있으면 따옴표로 감싸야 할 수 있습니다.
- 같은 계층에 중복 필드가 있으면 파서에 따라 처리 결과가 달라질 수 있습니다.
- 응답 헤더의 Content-Type은 단서가 될 수 있지만, 이것만으로 콘텐츠의 유효성을 판단할 수는 없습니다.
세 번째 단계: User-Agent와 요청 동작 비교
일부 구독 API는 User-Agent에 따라 서로 다른 형식을 반환합니다. 예를 들어 브라우저에는 안내 페이지를, Clash 또는 mihomo에는 YAML을 반환할 수 있으며, User-Agent에 따라 호환 필드를 선택하는 API도 있습니다. 브라우저 테스트는 200인데 클라이언트는 403 또는 HTML을 받는다면 YAML을 바로 수정하지 말고 요청 특성을 비교해야 합니다.
curl로 일반적인 mihomo 요청 식별자를 모방할 수 있습니다. 먼저 기본 요청을 테스트한 다음 지정한 User-Agent로 테스트하세요. 두 결과의 상태 코드, 파일 크기 또는 본문 형식이 뚜렷하게 다르면 문제는 대개 서버의 식별 로직에 있습니다:
curl -L -A "clash.meta" \
--connect-timeout 10 \
--max-time 30 \
-o subscription-mihomo.yaml \
"구독 주소"
clash.meta를 지정했을 때 YAML이 반환되고 기본 요청에서는 웹페이지가 반환된다면, 클라이언트에서 제공하는 구독 User-Agent 설정을 우선 사용하거나 구독 제공자에게 권장 값을 문의하세요. 그래픽 클라이언트마다 메뉴 위치는 다르지만, 일반적으로 “설정”→“구독 설정” 또는 개별 설정의 “편집”→“요청 헤더”에 있습니다. 변경 전에 기존 값을 기록해 전역 요청 헤더가 다른 설정에 잘못 적용되지 않도록 하세요.
요청 제한과 캐시도 함께 점검
“업데이트”를 연속해서 누르면 수십 초 안에 여러 요청이 전송됩니다. 서버는 토큰, IP 또는 User-Agent별로 요청 횟수를 계산한 뒤 429, 403 또는 일시적인 빈 응답을 반환할 수 있습니다. 이 경우 10~30분 동안 업데이트를 중지한 후 한 번만 요청하세요. 데스크톱, 휴대폰, 라우터에서 같은 주소를 동시에 반복 요청하지 마세요.
클라이언트 캐시 때문에 “링크는 고쳤지만 이전 오류가 계속 표시되는” 것처럼 보일 수도 있습니다. 먼저 설정 목록에서 설정 이름과 변경 내용을 기록한 다음 실패한 원격 설정을 삭제하고 다시 가져오세요. 아직 작동 중인 로컬 설정을 바로 덮어쓰지는 마세요. 클라이언트에서 설정 파일 디렉터리를 확인할 수 있다면 캐시 파일의 수정 시각과 크기도 비교하세요. 수정 시각이 변하지 않았다면 다운로드 단계의 실패에 가깝고, 시각은 변했지만 활성화할 수 없다면 파싱 또는 코어 로딩 문제일 가능성이 큽니다.
네 번째 단계: mihomo 코어와 설정 필드의 호환성 확인
구독이 정상적으로 다운로드된 뒤에도 코어의 파싱 과정을 거쳐야 합니다. Clash Premium, 구버전 Clash, Clash Meta, 최신 mihomo는 프로토콜 필드와 기능 지원 범위가 완전히 같지 않습니다. 구독 서비스가 템플릿을 업데이트하면 구형 코어가 인식하지 못하는 프록시 유형, 전송 매개변수, DNS 필드 또는 규칙 제공자 옵션이 추가될 수 있습니다. 그 결과 같은 주소가 최신 클라이언트에서는 작동하지만 오랫동안 업데이트하지 않은 클라이언트에서는 오류가 발생합니다.
로그에서 구체적인 필드 찾기
클라이언트의 “설정”→“로그”를 열고 로그 수준을 일시적으로 info 또는 debug로 설정한 뒤 구독 업데이트나 설정 전환을 한 번 실행하세요. 완료 후에는 원래 로그 수준으로 되돌리세요. 다음 정보를 중점적으로 확인합니다:
- unsupported proxy type: 현재 코어가 구독에 포함된 프록시 유형을 지원하지 않습니다.
- field ... not found 또는 역직렬화 오류: 필드 이름, 값 유형 또는 버전 호환성에 문제가 있습니다.
- proxy ... not found: 프록시 그룹이 존재하지 않는 노드나 다른 프록시 그룹을 참조합니다.
- rule provider ... error: 기본 설정은 로드되었지만 외부 규칙 컬렉션의 다운로드 또는 파싱에 실패했습니다.
- bind: address already in use: 설정 파싱은 성공했을 수 있으며, 7890 같은 포트가 이미 사용 중인 단계에서 실패한 것입니다.
코어 호환성 문제는 먼저 클라이언트에 내장된 코어 업데이트 기능으로 처리하세요. 일반적인 위치는 “설정”→“코어”→“업데이트 확인”입니다. 업데이트 후 클라이언트를 완전히 종료했다가 다시 시작하고, 로그에 표시되는 실제 코어 버전이 바뀌었는지 확인하세요. 그래픽 인터페이스만 업데이트하고 이전 코어를 계속 사용하면 오류가 사라지지 않습니다.
구독 파싱 실패와 규칙 제공자 실패 구분
전체 설정은 원격 proxy-providers와 rule-providers를 계속 참조할 수 있습니다. 기본 구독을 성공적으로 다운로드했다고 해서 이러한 하위 리소스까지 모두 접근할 수 있다는 뜻은 아닙니다. 노드 목록은 존재하지만 설정을 전환할 때 규칙 컬렉션 오류가 표시된다면 기본 구독을 다시 생성하지 말고 로그에 기록된 구체적인 URL, HTTP 상태, 캐시 경로를 확인하세요.
예를 들어 기본 설정은 직접 연결로 접근할 수 있지만 규칙 컬렉션 주소에는 프록시가 필요할 수 있습니다. 클라이언트 시작 시 프록시가 아직 준비되지 않았다면 시작 의존성이 생길 수 있습니다. 관련 원격 규칙을 잠시 비활성화해 기본 설정이 실행되는지 확인한 다음 규칙 컬렉션의 다운로드 경로 또는 업데이트 정책을 조정하세요. YAML을 수정한 뒤에는 먼저 들여쓰기를 확인하고 클라이언트의 설정 검사 기능으로 불러오세요.
다섯 번째 단계: 로컬 네트워크, DNS, 프록시 루프 확인
먼저 시스템 프록시를 끈 상태에서 테스트
구독 업데이트는 일반적으로 클라이언트가 직접 요청하지만, 클라이언트에 따라 직접 연결하거나 시스템 프록시를 사용하거나 현재 프록시 정책을 통해 접근할 수 있습니다. 현재 노드가 이미 만료되었고 구독 도메인까지 해당 노드로 전송되면 “노드를 복구하려면 구독을 업데이트해야 하지만, 구독 업데이트도 만료된 노드에 의존하는” 루프가 발생합니다.
- 현재 설정과 프록시 그룹 선택을 기록하세요.
- “설정”→“시스템 프록시”를 끄세요.
- TUN 모드가 활성화되어 있다면 “설정”→“TUN 모드”도 끄세요.
- 7890, 7891 또는 7892 포트를 사용하는 다른 프록시 프로그램을 종료하세요.
- 직접 연결 네트워크에서 구독 주소를 다시 테스트하세요.
- 업데이트가 완료되면 시스템 프록시와 TUN을 차례로 다시 활성화하세요.
시스템 프록시와 TUN을 끈 직후 정상으로 돌아온다면 원인은 대개 구독 형식이 아니라 라우팅 규칙, 현재 정책 또는 프록시 루프입니다. 구독 도메인이 잘못 프록시 정책으로 전달되고 있는지 확인하고, 해당 도메인에 명확한 직접 연결 규칙을 추가하세요. 이 규칙은 포괄적인 프록시 규칙보다 앞에 있어야 합니다.
rules:
- DOMAIN,subscription.example.com,DIRECT
- MATCH,PROXY
위 도메인은 구조를 보여 주기 위한 예시일 뿐이며, 실제 설정에는 구독 서비스의 호스트 이름을 입력해야 합니다. 구독이 여러 번 리디렉션된다면 최종 리디렉션 도메인도 확인하세요. 진입 도메인만 허용하면 두 번째 리디렉션에서 여전히 실패할 수 있습니다.
DNS, 시스템 시간, TLS 확인
터미널에서 nslookup 구독 도메인을 실행해 주소가 반환되는지 확인하세요. 브라우저는 보안 DNS를 사용하지만 시스템 확인이 실패하면 클라이언트가 브라우저의 확인 결과를 재사용하지 못할 수 있습니다. 휴대폰 핫스팟처럼 다른 네트워크로 잠시 전환해 다시 테스트할 수도 있습니다. 네트워크를 바꾼 뒤 정상으로 돌아온다면 현재 DNS, 라우터 필터링 또는 네트워크 출구에 문제가 있을 가능성이 큽니다.
TLS 인증서 검증에는 올바른 시스템 시간도 필요합니다. 기기 날짜가 하루 어긋났거나 시간대가 잘못되었거나 장기간 동기화되지 않으면 certificate has expired, not yet valid 같은 오류가 발생할 수 있습니다. Windows 11에서는 “설정”→“시간 및 언어”→“날짜 및 시간”→“지금 동기화”로 이동하고, macOS에서는 “시스템 설정”→“일반”→“날짜 및 시간”에서 자동 설정을 활성화하세요.
방화벽이나 보안 소프트웨어가 브라우저에는 영향을 주지 않고 클라이언트 프로세스만 제한할 수도 있습니다. 시스템 방화벽 허용 목록을 확인해 현재 Clash 그래픽 클라이언트와 mihomo 코어 프로세스가 모두 외부 연결을 설정할 수 있는지 확인하세요. 테스트를 위해 방화벽을 장기간 끄지는 마세요. 차단 기록을 확인하고 해당 프로그램에 범위가 명확한 아웃바운드 규칙을 만드는 편이 좋습니다.
정해진 순서로 전체 자가 점검 수행
여러 변수가 동시에 바뀌는 것을 피하려면 다음 순서대로 진행하세요. 각 단계를 완료할 때마다 한 번만 테스트하고 상태 코드, 파일 크기 또는 로그 변화를 기록하세요. 이렇게 하면 어떤 조정이 효과를 냈는지 명확히 알 수 있습니다.
- 현상 보존: 오류 원문, 발생 시각, 클라이언트 버전, 코어 버전, 현재 네트워크를 기록합니다.
- URL 확인: 링크가 잘리지 않았고 계정이 유효하며 토큰이 재설정되지 않았는지 확인합니다.
- HTTP 확인: 연결 시간 제한 10초, 전체 제한 시간 30초로 상태 코드와 리디렉션을 테스트합니다.
- 본문 확인: HTML 로그인 페이지, JSON 오류, 빈 파일, 다운로드 중단을 제외합니다.
- 유형 확인: 전체 YAML, 프록시 컬렉션, 범용 노드 목록을 구분합니다.
- 요청 헤더 비교: 기본 User-Agent와 clash.meta의 응답 차이를 테스트합니다.
- 호환성 확인: 클라이언트 코어를 업데이트하고 로그에서 지원되지 않는 필드나 프로토콜을 찾습니다.
- 네트워크 변수 분리: 시스템 프록시와 TUN을 잠시 끄고 직접 연결 또는 휴대폰 핫스팟으로 테스트합니다.
- 다시 가져오기: 기존 설정을 백업한 뒤 실패한 캐시를 삭제하고 원격 설정을 다시 추가합니다.
- 결과 확인: 노드 수, 프록시 그룹, 규칙 컬렉션, 업데이트 시간이 예상대로인지 확인합니다.
| 테스트 결과 | 도출할 수 있는 결론 | 다음 단계 |
|---|---|---|
| 모든 네트워크에서 401 또는 403 반환 | 링크 권한 또는 서버 제한 문제일 가능성이 큼 | 계정 상태를 확인하고 구독 주소를 재설정하거나 제공자에게 문의 |
| 휴대폰 핫스팟에서는 작동하지만 기존 네트워크에서 시간 초과 | 기존 네트워크의 DNS, 라우팅 또는 출구에 문제가 있음 | 라우터, 시스템 DNS, 방화벽 기록 확인 |
| curl에서는 YAML을 받지만 클라이언트는 계속 실패 | 요청 헤더, 캐시 또는 코어 호환성 문제일 가능성이 큼 | 클라이언트 로그 확인 및 코어 업데이트 |
| 기본 설정은 성공하지만 규칙 컬렉션은 실패 | 기본 구독 자체는 유효함 | rule-providers 주소와 정책을 별도로 점검 |
| TUN을 끄면 업데이트 성공 | 라우팅 루프 또는 시작 의존성이 존재함 | 구독 도메인 규칙과 업데이트 경로 조정 |
복구 후에도 설정이 실제로 작동하는지 확인해야 함
구독 페이지에 “업데이트 성공”이 표시되는 것은 첫 번째 검증일 뿐입니다. 설정 업데이트 시간이 갱신되었는지, 노드 목록이 비어 있지 않은지, 프록시 그룹 참조가 정상인지 확인하고 지연 시간 테스트도 실행하세요. 지연 시간 테스트에서 85ms 또는 230ms처럼 구체적인 값이 반환되면 해당 노드를 통해 테스트 URL에 연결할 수 있다는 뜻입니다. 계속 시간 초과가 표시되면 노드 또는 로컬 네트워크를 추가로 점검해야 합니다.
그다음 연결 패널을 열고 일반 HTTPS 페이지에 접속해 새 연결이 표시되는지 확인하세요. 해당 연결에 어떤 규칙이 적용되었고 어떤 프록시 그룹과 노드를 사용했는지도 살펴보세요. 규칙 모드에서는 구독 사이트를 직접 연결하고 다른 대상은 규칙에 따라 분류할 수 있으며, 전역 모드에서는 대부분의 트래픽이 현재 전역 정책으로 전달됩니다. 검증할 때 현재 모드가 예상과 일치하는지 확인하세요.
시스템 프록시가 기본 혼합 포트 7890을 사용한다면 운영체제 프록시 주소가 127.0.0.1:7890인지 확인하고 로그에 포트 사용 오류가 없는지도 살펴보세요. TUN 사용자는 TUN 상태, 기본 라우팅, DNS가 복구되었는지 확인해야 합니다. 브라우저 캐시 페이지가 열리는지만으로 연결 성공을 판단하지 마세요.
안정화된 후에는 원격 설정의 자동 업데이트 간격을 6시간, 12시간, 24시간처럼 적절한 값으로 설정할 수 있습니다. 분 단위 폴링은 대개 필요하지 않으며 서버의 요청 빈도 제한을 유발할 수 있습니다. 클라이언트 업그레이드, 코어 전환 또는 구독 템플릿 변경 후에는 수동 업데이트와 설정 검사를 한 번 수행하면 충분합니다.