← 블로그 목록
웹 개발작성 · 7분 읽기

Unexpected end of JSON input 오류 원인과 해결 — 빈 응답·204·HEAD·no-cors (크롬·Node 실측)

SyntaxError: Unexpected end of JSON input 은 짧고 불친절한 메시지라, 설명 글도 원인을 한꺼번에 늘어놓기 쉽습니다. 작은 로컬 서버를 만들어 크롬 154, Node.js 24, 파이썬 3.11 에서 경우를 하나씩 재현해 봤습니다. 결과는 꽤 좁혀집니다. 지금의 크롬·Node 에서 이 문구는 읽을 내용이 아예 없을 때 나옵니다. 중간에 잘린 JSON 은 위치가 붙은 다른 메시지가 나고, no-cors 요청은 JSON 이라는 단어가 빠집니다. 경우마다 실제 문구, 왜 그런지, 그리고 막는 fetch 코드를 정리했습니다.

JSON 포매터 & 검증기 (무료, 브라우저 안에서) — 실제 실행 화면
실제 실행 화면
이 글에서 소개하는 무료 도구
JSON 포매터 & 검증기 (무료, 브라우저 안에서)

서버가 실제로 보낸 내용을 붙여넣으면 올바른 JSON 인지, 어디서 깨졌는지 줄·칸으로 보여 줍니다. 브라우저 안에서만 처리해 어디로도 보내지 않습니다.

  • ✓ 무료
  • ✓ 설치·회원가입 없음
  • ✓ 브라우저에서 바로 실행
  • ✓ 파일이 서버로 올라가지 않음

🔒 파일을 서버나 다른 어떤 곳으로도 보내지 않습니다 — 내 컴퓨터의 브라우저 안에서만 처리합니다.

이동할 주소 — 지금 보고 있는 이 사이트(coding-now.com) 안의 페이지입니다
🔒 https://www.coding-now.com/json-formatter

메시지가 뜻하는 것 — 직접 재 봤습니다

같은 입력을 크롬 154·Node.js 24.13 의 JSON.parse 와 파이썬 json.loads 에 넣었습니다. 크롬과 Node 의 메시지는 똑같았습니다. Unexpected end of JSON input 은 입력이 비었거나 공백뿐일 때만 나왔고, 그 밖에 일찍 끝난 입력은 더 구체적인 메시지가 나왔습니다.

입력크롬 154 / Node 24파이썬 3.11
"" (빈 문자열)Unexpected end of JSON inputExpecting value: line 1 column 1 (char 0)
" " (공백)Unexpected end of JSON inputExpecting value: line 1 column 4 (char 3)
{"ok":true,"items":[1,2Expected ',' or ']' after array element in JSON at position 23 (line 1 column 24)Expecting ',' delimiter: line 1 column 24 (char 23)
{"ok":true,"name":"helUnterminated string in JSON at position 22 (line 1 column 23)Unterminated string starting at: line 1 column 19 (char 18)
{Expected property name or '}' in JSON at position 1 (line 1 column 2)Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

그러니 지금의 브라우저나 Node 에서 정확히 이 문구를 봤다면 깨진 JSON 이 아니라 빈 문자열을 찾아야 합니다. 잘린 파일이 이 메시지를 낸다는 설명 글이 많은데, 예전 엔진 버전에서는 그랬을 수 있습니다(예전 버전은 시험하지 않았습니다). 다른 브라우저는 문구가 다릅니다 — MDN 의 JSON.parse 오류 문서에는 JSON.parse: unexpected end of data 같은 표현이 실려 있습니다.

res.json() 이나 JSON.parse 가 무엇을 받았는지에 따라 문구가 갈립니다. 로컬 시험 서버로 크롬 154·Node 24 에서 실측.

빈 본문은 어디서 오나

빈 문자열은 거의 언제나 응답 본문입니다. 경우마다 경로 하나씩 돌려주는 로컬 서버를 만들고, 크롬 페이지와 Node 의 기본 fetch 에서 각각 res.json() 을 불렀습니다.

  • 204 No Content — 삭제나 저장 뒤에 흔합니다. 상태 204 에 Content-Length 가 없었고 res.text() 는 빈 문자열이었습니다. res.json() 은 Unexpected end of JSON input.
  • HEAD 요청 — 같은 주소의 GET 이 JSON 을 줘도 HEAD 에는 본문이 없습니다. 같은 오류.
  • 본문 없는 200 — 서버 버그나, 성공 때 아무것도 안 돌려주는 주소. 같은 오류.
  • 본문 없는 500(404 도) — fetch 는 HTTP 오류에서 멈추지 않아서 코드가 빈 오류 본문을 그대로 파싱합니다. 크롬은 이때만 Failed to execute 'json' on 'Response': Unexpected end of JSON input 처럼 앞말을 붙였고, Node 는 붙이지 않았습니다.

마지막 경우는 파이썬이 다릅니다. urllib.request.urlopen 은 JSON 을 읽기 전에 HTTP Error 500: Internal Server Error 로 먼저 멈췄습니다. 파이썬에서는 빈 오류 본문이 JSON 오류가 아니라 HTTP 오류로 드러납니다.

mode: 'no-cors' — 'Unexpected end of input'

CORS 오류를 피하려고 mode: 'no-cors' 를 넣었다면, 요청은 성공해도 답을 읽을 수 없습니다. 다른 출처의 JSON 을 그렇게 불렀더니 응답은 type opaque, status 0 이었고, text 는 비어 있었고, res.json() 은 Unexpected end of input 을 냈습니다 — 이 경우엔 JSON 이라는 단어가 빠집니다.

no-cors 는 CORS 를 우회하는 방법이 아니라 '답은 안 읽겠다'고 약속하고 요청만 보내는 방법입니다. 다른 출처의 JSON 을 읽으려면 그 서버가 CORS 헤더를 보내거나, 내 서버를 거쳐서 불러야 합니다.

본문을 두 번 읽으면 다른 오류

응답 본문은 한 번만 읽을 수 있습니다. res.text() 뒤에 res.json() 을 부르면(로그를 찍느라 먼저 읽은 경우가 흔합니다) 크롬은 Failed to execute 'json' on 'Response': body stream already read, Node 는 Body is unusable: Body has already been read 였습니다. 한 번 읽어 변수에 담거나, 처음 읽기 전에 res.clone() 을 해 둡니다.

해결: 확인하고 나서 파싱

빈 본문을 사고가 아니라 있을 수 있는 답으로 다룹니다. 아래 함수는 시험 서버에서 204·HEAD·빈 200 은 null 을 돌려주고, 500 은 HTTP 오류를 분명하게 던졌습니다.

javascript
async function getJson(url, options) {
  const res = await fetch(url, options);
  if (!res.ok) throw new Error(`HTTP ${res.status} for ${url}`);
  if (res.status === 204) return null;
  const text = await res.text();
  if (!text.trim()) return null;      // 빈 본문: 파싱할 게 없음
  return JSON.parse(text);             // 진짜 JSON 오류라면 이제 위치가 나온다
}

파이썬도 같은 생각입니다. 바이트를 읽고, 뭔가 왔을 때만 파싱합니다.

python
import json, urllib.request

with urllib.request.urlopen(url) as r:
    body = r.read()
data = json.loads(body) if body.strip() else None

그래도 실패하면 res.status, res.headers.get('content-type'), 그리고 text 앞 200자를 찍어 보세요. text 가 < 로 시작하면 서버가 HTML 을 보낸 것이고, 그건 이 사이트의 JSON 파싱 오류 가이드에서 다룬 Unexpected token '<' 오류입니다.

자주 묻는 질문

Q. Unexpected end of JSON input 이면 JSON 이 깨진 건가요?

대개 아닙니다. 크롬 154·Node 24 에서는 입력이 비었거나 공백뿐일 때만 이 문구가 나왔습니다. 중간에 잘린 JSON 은 Expected ',' or ']' after array element in JSON at position 23 처럼 위치가 붙은 다른 메시지였습니다.

Q. 왜 가끔만 나나요?

서버가 가끔만 빈 본문을 보내기 때문입니다 — 삭제 뒤 204, 오류가 났을 때의 빈 응답 같은 경우입니다. 실패한 요청의 상태 코드를 찍어 보면 대개 204 나 4xx·5xx 입니다.

Q. JSON 이 빠진 'Unexpected end of input' 은 같은 오류인가요?

제 시험에서는 다른 출처에 mode: 'no-cors' 로 fetch 했을 때 나왔습니다. 응답이 opaque·status 0 이라 코드에서는 본문이 비어 보입니다. no-cors 를 빼고 서버의 CORS 설정을 고쳐야 합니다.

Q. .json 파일을 읽을 때 나요. 무엇을 보면 되나요?

파일이 0바이트이거나 공백뿐인지 보세요 — 빈 문자열을 JSON.parse 하면 정확히 이 메시지입니다. 중간에 잘린 파일이라면 위치가 붙은 다른 메시지가 나옵니다.

이 글에서 소개하는 무료 도구
JSON 포매터 & 검증기 (무료, 브라우저 안에서)

서버가 실제로 보낸 내용을 붙여넣으면 올바른 JSON 인지, 어디서 깨졌는지 줄·칸으로 보여 줍니다. 브라우저 안에서만 처리해 어디로도 보내지 않습니다.

  • ✓ 무료
  • ✓ 설치·회원가입 없음
  • ✓ 브라우저에서 바로 실행
  • ✓ 파일이 서버로 올라가지 않음

🔒 파일을 서버나 다른 어떤 곳으로도 보내지 않습니다 — 내 컴퓨터의 브라우저 안에서만 처리합니다.

이동할 주소 — 지금 보고 있는 이 사이트(coding-now.com) 안의 페이지입니다
🔒 https://www.coding-now.com/json-formatter

다른 글