YAML의 노르웨이 문제 — 따옴표 없는 NO가 false가 되는 이유
설정 파일에 debug: yes라고 쓰면 사람 눈에는 그냥 "예"라는 뜻으로 읽힙니다. YAML은 바로 이 가독성을 위해 태어난 포맷이라 실제로 이 문장을 불리언 true로 자동 변환해줍니다. 그런데 이 편의 기능이 뜻밖의 자리에서 발목을 잡습니다. 국가코드 목록에 노르웨이를 뜻하는 NO를 따옴표 없이 적었더니 문자열이 아니라 불리언 false로 파싱되어버린 사건이 개발자 커뮤니티에서 두고두고 회자되며 "노르웨이 문제(Norway Problem)"라는 별명까지 붙었습니다. 이 가이드에서는 이 기능이 왜 생겼는지, 왜 뒤늦게 문제가 됐는지, 그리고 이 사이트 도구가 실제로 어떤 규칙을 따르는지를 정리합니다.
1. YAML은 왜 no/yes/on/off를 불리언으로 봐줬나
YAML(YAML Ain't Markup Language)의 설계 목표는 JSON보다 사람이 읽고 쓰기 편한 데이터 포맷을 만드는 것이었습니다. 프로그래머가 아닌 사람도 설정 파일을 직관적으로 고칠 수 있어야 한다는 취지에서, YAML 1.1 스펙은 불리언 값을 true/false 한 쌍으로 제한하지 않고 사람이 실제 대화에서 쓰는 표현까지 폭넓게 허용했습니다. yes/no, on/off, y/n은 물론 대소문자 변형까지 전부 불리언으로 인식하도록 정의된 것입니다. 스위치를 켜고 끄는 설정값에 on, off라고 쓰면 자연스럽게 읽히니 실용적인 결정처럼 보였습니다.
2. 편의 기능이 뒤늦게 버그가 된 이유
문제는 YAML이 "이건 사람이 봐도 불리언 같으니 값이 아니라 타입을 바꿔주겠다"는 판단을 파서가 대신 내려버린다는 점입니다. 이 규칙은 설정 파일 작성자가 애초에 불리언 값을 의도했을 때는 잘 작동하지만, 우연히 불리언 후보 단어와 철자가 겹치는 문자열을 쓸 때는 조용히 데이터를 망가뜨립니다. 대표적인 사례가 ISO 3166 국가코드입니다. 노르웨이의 2자리 코드는 NO인데, 이를 국가 목록 YAML 파일에 따옴표 없이 적으면 파서가 문자열이 아니라 불리언 false로 읽어버립니다. 여러 오픈소스 프로젝트에서 국가코드 처리 로직이 노르웨이만 유독 빠지거나 이상하게 동작하는 버그로 실제 보고된 바 있고, 이 사례가 널리 알려지면서 "노르웨이 문제"라는 이름이 굳어졌습니다.
입력:
country: NOYAML 1.1 파서 결과:
country → false (불리언)YAML 1.2 파서 결과:
country → "NO" (문자열, 의도한 값 그대로)같은 한 줄이 파서 버전에 따라 완전히 다른 타입의 값으로 해석되는 것이 이 문제의 핵심입니다. 따옴표를 붙여
country: "NO"라고 쓰면 어느 파서를 쓰든 항상 문자열로 고정됩니다.
3. YAML 1.2는 이 문제를 어떻게 좁혔나
2009년 개정된 YAML 1.2 스펙은 이 혼란을 정면으로 다뤘습니다. 코어 스키마에서 불리언으로 자동 인식되는 문자열 범위를 true/false(및 True/TRUE 같은 대소문자 변형)로만 좁혔고, yes/no/on/off는 더 이상 특별 취급하지 않고 평범한 문자열로 남깁니다. 즉 YAML 1.2를 따르는 파서에서는 country: NO가 그대로 문자열 "NO"로 파싱됩니다. 다만 스펙이 바뀌었다고 모든 구현체가 곧바로 따라가는 것은 아닙니다. Python 생태계에서 널리 쓰이는 PyYAML의 기본 로더(yaml.load, yaml.safe_load)는 여전히 YAML 1.1 규칙 기반으로 동작하는 것으로 알려져 있어, 어떤 언어·라이브러리로 YAML을 읽느냐에 따라 같은 파일이 다르게 해석될 수 있다는 점을 실무에서는 늘 염두에 둬야 합니다.
4. 이 사이트 도구는 어느 규칙을 따르는가
YAML 유효성 검사기를 비롯해 이 사이트의 YAML 관련 도구는 자바스크립트 라이브러리 js-yaml 4.x를 파싱 엔진으로 사용하며, 이 라이브러리는 기본적으로 YAML 1.2 코어 스키마를 따릅니다. 따라서 이 도구에 country: NO를 입력해 검증하면 불리언 false가 아니라 문자열 "NO"로 정확히 파싱된 결과를 확인할 수 있습니다. 다만 이는 이 사이트 도구 한정 동작이며, 서버 백엔드에서 PyYAML 기본 로더처럼 YAML 1.1 규칙을 따르는 파서로 같은 파일을 다시 읽는다면 결과가 달라질 수 있습니다. 그래서 국가코드, on/off 스위치 값처럼 불리언 후보 단어와 겹치는 문자열은 파서 종류와 무관하게 항상 따옴표로 감싸는 것이 가장 안전한 습관입니다.
5. 정리 — YAML 작성 시 확인할 순서
- 불리언 후보 단어 확인: no, yes, on, off, y, n과 겹치는 문자열 값(국가코드, 스위치명 등)이 있는지 먼저 점검합니다.
- 애매한 값은 무조건 따옴표:
country: "NO"처럼 따옴표로 감싸면 어떤 파서를 쓰든 문자열로 고정됩니다. - 파서 버전 확인: 사용 중인 라이브러리가 YAML 1.1과 1.2 중 어느 쪽 규칙을 따르는지 문서에서 확인합니다.
- 검증 도구로 실제 파싱 결과 확인: 배포 전 YAML 유효성 검사기로 실제 파싱된 구조를 눈으로 확인합니다.
자주 묻는 질문
Q. YAML의 노르웨이 문제(Norway Problem)가 정확히 무엇인가요?
A. YAML 1.1 스펙에서는 따옴표 없이 쓴 no, yes, on, off, y, n 같은 단어를 자동으로 불리언 true/false로 해석합니다. 이 때문에 ISO 3166 국가코드 NO(노르웨이)를 따옴표 없이 country: NO라고 쓰면 문자열 'NO'가 아니라 불리언 false로 파싱돼버리는 유명한 버그가 생겼고, 이를 노르웨이 문제라고 부릅니다.
Q. YAML 1.1과 1.2는 불리언 처리에서 뭐가 다른가요?
A. YAML 1.1은 y, Y, yes, Yes, YES, n, N, no, No, NO, true, True, TRUE, false, False, FALSE, on, On, ON, off, Off, OFF까지 폭넓게 불리언으로 인식합니다. 2009년 개정된 YAML 1.2 코어 스키마는 이 범위를 true/false(및 대소문자 변형)로만 좁혀서, no나 on 같은 단어는 더 이상 자동으로 불리언 취급되지 않고 그냥 문자열로 남습니다.
Q. 이 사이트의 YAML 도구는 어느 버전 규칙을 따르나요?
A. yaml-validator.html 등 이 사이트의 YAML 관련 도구는 js-yaml 4.x 라이브러리를 사용하며, 이 라이브러리는 YAML 1.2 코어 스키마를 기본으로 따릅니다. 따라서 country: NO를 검증하면 false가 아니라 문자열 'NO'로 정확히 파싱됩니다.
Q. 실무에서는 왜 아직도 이 문제가 언급되나요?
A. PyYAML의 기본 로더(yaml.load, yaml.safe_load)를 비롯한 일부 널리 쓰이는 파서가 여전히 YAML 1.1 규칙을 따르기 때문입니다. 라이브러리마다 실제 동작이 다를 수 있으므로, 국가코드나 on/off 같은 값을 YAML에 쓸 때는 파서 버전과 무관하게 항상 따옴표를 붙이는 습관이 안전합니다.