unmarshal 오류가 말해 주는 것

Clash Meta(mihomo 계열 코어)는 시작할 때 config.yaml(또는 GUI가 만든 동일 구조의 프로필)을 읽어 Go 언어의 YAML 파서로 구조체에 채웁니다. 이 단계에서 문법이 깨지면 로그에 unmarshal·yaml·parse 같은 단어가 함께 뜨고, 코어는 프로필을 로드하지 못한 채 종료되거나 클라이언트에 “설정을 불러올 수 없음”만 남깁니다. 이때 문제는 대개 네트워크나 노드 품질이 아니라 파일 텍스트 자체이므로, 트래픽 규칙을 아무리 잘 짜도 구문 수준에서 막히면 실행 단계까지 가지 못합니다.

사용자 입장에서는 “방금 구독만 갱신했는데 왜 안 되지?”처럼 보이지만, 실제로는 병합된 결과물이나 수동으로 붙여 넣은 블록 때문에 최상위 키가 두 번 나오거나, 한 줄의 들여쓰기만 어긋나 proxies 아래 항목이 맵이 아닌 이상한 형태로 해석되는 경우가 많습니다. 본문은 특정 GUI 이름을 가정하지 않고, 로그에 찍힌 위치 정보YAML 규칙만으로 되돌리는 순서에 집중합니다. 전체 흐름은 문서 허브의 프로필·기능 안내와 함께 보면 “어떤 섹션이 한 번만 와야 하는지” 감이 잡힙니다.

첫 단계: 로그에서 줄 번호·키 이름 잡기

대부분의 클라이언트는 코어 로그를 파일이나 화면에 남깁니다. unmarshal failed·cannot unmarshal·yaml: 류 문구 근처에 line 123 같은 표기가 붙어 있으면, 그 줄을 편집기에서 바로 열어보세요. 줄 번호가 없고 “duplicate key”만 있다면, 메시지에 나온 키 이름(예: proxy-groups, rules, proxies)으로 전체 검색하는 것이 가장 빠릅니다. 한 파일 안에 같은 최상위 키가 두 번 있으면 파서가 어느 쪽을 택해야 할지 모호해지므로, Meta 계열에서는 흔히 여기서 걸립니다.

로그를 열기 어렵다면, 프로필을 연 동일한 텍스트 편집기에서 “문제가 된 직후에 저장한 버전”과 “작동하던 백업”을 비교(diff)하는 방법도 있습니다. 구독 URL만 바꿨는데 규칙 전체가 바뀌었다면, 제공자 템플릿이 rules: 블록을 통째로 또 넣었을 가능성을 의심하세요. 구독 운영과 형식에 대한 배경은 구독 관리 실전 글에서 다룬 자동 갱신·병합 맥락과 연결됩니다.

들여쓰기: 스페이스·탭 혼용과 레벨 불일치

YAML은 들여쓰기로 계층을 나눕니다. Clash 프로필에서 흔한 규칙은 “한 단계마다 스페이스 두 칸”인데, 중간에 탭 문자가 섞이거나, 복사한 블록만 스페이스 네 칸 기준이면 같은 시각적 깊이라도 파서가 다른 레벨로 읽어 매핑 오류를 냅니다. 편집기에서 보이지 않는 문자 표시를 켜면 탭이 하이라이트되어 원인을 바로 볼 수 있습니다.

또 하나의 전형은 리스트 항목(- name: ...) 아래 필드가 리스트에 속해야 하는데, 한 줄만 들여쓰기가 덜 되어 이전 키와 형제가 되어 버리는 경우입니다. 이때 unmarshal 메시지는 “필드를 구조체에 넣을 수 없다”처럼 추상적으로 나올 수 있으므로, 로그가 가리킨 줄 위아래 세 줄을 포함해 블록 전체의 들여쓰기 깊이를 맞추면 해결되는 경우가 많습니다. 코어 버전별 필드 이름은 Meta 업그레이드·마이그레이션 가이드와 맞춰 두면, 존재하지 않는 키를 넣었다가 생기는 오류와 구분하기도 쉬워집니다.

# Indentation example — use spaces consistently per level
proxy-groups:
  - name: Auto
    type: url-test
    proxies:
      - node-a
      - node-b

중복 키: proxy-groups·rules·proxies가 두 번

단일 YAML 문서에서 proxies:·proxy-groups:·rules: 같은 최상위(또는 프로필 루트에 가까운) 키는 보통 한 번만 정의됩니다. 사용자가 “규칙만 추가하려다” 파일 끝에 rules: 블록을 통째로 또 붙이거나, 구독에서 내려온 조각과 로컬 규칙 조각을 단순 연결하면 같은 키가 두 번 나오기 쉽습니다. 일부 파서는 나중 값을 덮어쓰기도 하지만, 검증 단계에서 실패하거나 클라이언트가 “유효하지 않은 프로필”로 거절할 수 있어, Meta 쪽에서는 처음부터 한 블록으로 합치는 것이 안전합니다.

해결 절차는 단순합니다. ① 파일에서 ^rules:·^proxy-groups: 등을 검색해 등장 횟수를 센다. ② 두 번 이상이면, 의도한 규칙·그룹만 남기고 나머지는 삭제하거나, 아래쪽 블록의 항목을 위쪽 리스트에 병합한다. ③ proxy-groups가 참조하는 proxies 이름이 실제 proxies: 목록에 있는지도 함께 확인한다(이름 불일치는 다른 종류의 오류로 이어질 수 있음). 규칙 문법 자체를 다듬는 단계는 규칙 심화 가이드와 짝을 이룹니다.

팁: “위쪽 rules:는 오래된 잔재이고 아래쪽만 쓰고 싶다”면, 위쪽 블록을 지우기 전에 백업 파일에 통째로 복사해 두세요. 나중에 필요한 한 줄이라도 있으면 diff로 되살리기 쉽습니다.

구독 가져오기·병합 후에만 터지는 경우

GUI가 “구독을 프로필에 병합”할 때, 원격에서 내려온 YAML 조각에 이미 proxy-groups가 포함되어 있는데 로컬에도 동일 섹션이 있으면 충돌합니다. 이때는 어느 쪽을 단일 소스로 할지 먼저 정하고, 클라이언트의 “구독만 덮어쓰기 / 전체 덮어쓰기” 옵션을 맞추는 편이 낫습니다. 원격이 규칙까지 제공한다면 로컬에서 손댄 rules:가 날아갈 수 있으니, 의도한 동작인지 확인해야 합니다.

반대로, 구독은 proxies만 채우고 rules는 항상 로컬에서 관리하는 구성이라면, 병합 결과에서 rules:한 번만 나오게 템플릿을 통일하는 것이 장기적으로 덜 지저분합니다. 자동 갱신 직후에만 오류가 난다면, 그 시점에 받은 원문을 파일로 저장해 중복 키가 생겼는지 먼저 보는 것이 좋습니다.

검증: 편집기·CLI로 YAML을 미리 걸러내기

코어에 넣기 전에 yamllint나 VS Code의 YAML 확장, 온라인이 아닌 로컬 도구로 문법 검사를 한 번 거치면, 들여쓰기·따옴표·리스트 형식 문제를 빠르게 걸러낼 수 있습니다. 다만 Clash 전용 키는 일반 스키마가 없어 “경고는 많아도 실행은 된다”는 경우도 있으므로, 에러 수준 메시지와 코어 로그를 함께 보는 것이 좋습니다. 팀 저장소에 프로필을 올릴 때는 민감한 구독 URL·노드 비밀번호가 섞이지 않게 주의하세요.

Windows·macOS·Linux 공통으로, “저장 후 즉시 실패” 루프에 빠지지 않으려면 작동 확인된 파일을 복사본으로 남겨 두고, 문제가 되는 변경만 작은 단위로 적용하는 습관이 가장 확실합니다. 앞서 언급한 구독 관리 글의 백업 권장과도 같은 맥락입니다.

복구 워크플로: 백업 → 줄 번호 → 한 번에 하나만 고치기

정리하면 다음 순서를 권합니다. ① 현재 깨진 프로필을 그대로 다른 이름으로 복사해 둔다. ② 코어·클라이언트 로그에서 줄 번호 또는 키 이름을 확인한다. ③ 해당 위치에서 들여쓰기·탭·중복 키 중 무엇인지 판별한다. ④ 수정 후 한 번만 다시 로드해 본다. ⑤ 같은 오류가 반복되면, 다음으로 가리키는 줄로 이동한다. 한 번에 여러 군데를 손대면 어느 변경이 효과였는지 알기 어렵습니다.

그래도 복구가 어렵다면, 공식 예제에 가까운 최소 프로필(포트·DNS·빈 proxies·단순 rules: MATCH,DIRECT 수준)으로 시작해, 구독·규칙을 단계적으로 다시 붙여 넣는 방법이 있습니다. 이때도 각 단계마다 저장·로드가 성공하는지 확인하면, 문제가 재현되는 지점을 좁힐 수 있습니다.

Clash는 로컬 프록시 엔진일 뿐이며, 타인의 구독이나 규칙을 무단으로 재배포해서는 안 됩니다. 불법적인 우회 목적에 쓰이지 않도록 각 국가·지역의 법규를 준수하세요.

정리: 문법을 통과해야 규칙과 노드가 살아난다

YAML은 사람이 읽기 쉬운 대신, 공백 한 칸이 곧 문법입니다. Clash Meta에서 unmarshal 단계에 걸리면 설정이 아무리 정교해도 켜지지 않으므로, 로그의 줄 번호와 중복 키 검색부터 습관화하는 것이 좋습니다. 들여쓰기·구독 병합·수동 편집은 모두 같은 실수로 이어질 수 있지만, 위 순서대로면 대부분 “시작 불가” 상태에서 벗어날 수 있습니다. 같은 목적의 클라이언트라도 편집기·검증 기능이 잘 갖춰진 쪽이 일상적인 마찰이 적습니다. 커뮤니티 자료와 호환성 면에서 Clash·mihomo 기반 앱은 균형이 잘 잡힌 편입니다.

→ Clash 공식 클라이언트 무료 다운로드 — 프로필 편집과 구독 관리가 한 화면에서 잡히는 빌드를 쓰고 싶다면, 최신 패키지를 받아 직접 맞춰 보는 것이 가장 빠릅니다.