본문 바로가기
IT

Unexpected end of JSON input — JSON.parse 원인·해결·예방

by 샤나엘 2026. 7. 1.
반응형

Unexpected end of JSON input — JSON.parse 원인·해결·예방

서버 응답을 받아 처리하다 "SyntaxError: Unexpected end of JSON input"이 뜨면, JSON.parse가 문자열을 읽다가 끝을 예상보다 일찍 만났다는 뜻이다. 쉽게 말해 파싱하려던 JSON이 중간에 잘렸거나 아예 비어 있는 것이다. 가장 흔한 경우가 빈 응답 본문을 JSON으로 파싱하려 할 때, 즉 서버가 아무 내용도 안 보냈는데 res.json()이나 JSON.parse를 돌린 상황이다. 빈 문자열을 파싱하거나, 네트워크가 끊겨 데이터가 잘렸을 때도 난다. 같은 SyntaxError라도 "Unexpected token"이 형식이 틀린 글자를 만난 것이라면, 이건 형식과 상관없이 "끝이 너무 빨리 왔다"는 신호다. 이 글은 이 에러의 의미, 원인, 그리고 빈 값 체크와 try-catch를 비롯한 해결을 정리한다.

Unexpected end of JSON input — JSON.parse 원인·해결·예방

 

이 글의 구성

 

🔎에러 메시지의 의미
⚖️end of input vs Unexpected token
🧩자주 나오는 발생 원인 4가지
💻재현과 진단
🛠해결 방법과 예방
💬자주 묻는 질문 5가지

🔎 에러 메시지의 의미

이 에러는 JSON.parse가 던지는 SyntaxError다. JSON.parse는 문자열을 받아 그것이 올바른 JSON인지 처음부터 끝까지 읽어 나가는데, 완결된 값을 다 만들기도 전에 문자열이 끝나버리면 "입력이 예상보다 빨리 끝났다"며 멈춘다. 값을 채우기도 전에 문자열이 끊겼거나(여는 괄호와 키까지만 오고 값이 안 온 상태), 파싱할 내용이 아예 없는(빈 문자열·공백만 있는) 경우다.

 

가장 대표적인 형태가 빈 응답을 파싱하는 것이다. 서버가 본문 없이 응답했는데 그 빈 내용을 JSON으로 바꾸려 하면 이 에러가 난다. fetch에서 await res.json()을 부를 때, 응답 본문이 비어 있으면 내부적으로 빈 문자열을 파싱하다 여기서 터진다. 즉 "받은 게 잘렸거나 비었다"는 신호이지, 데이터의 글자 하나가 틀렸다는 신호는 아니다.

핵심 — 내용이 잘렸거나 비었다

이 에러는 파싱하려던 문자열이 완결되지 않았다는 뜻이다. 대부분 빈 응답이거나 잘린 데이터다. 그래서 디버깅의 첫걸음은 "파싱하기 직전 문자열이 실제로 무엇인지" 확인하는 것이다. JSON.parse에 넘기기 전 그 값을 그대로 찍어 보면, 빈 문자열인지 잘린 조각인지 바로 드러난다.


⚖️ end of input vs Unexpected token

같은 JSON.parse의 SyntaxError지만, "Unexpected end of JSON input"과 "Unexpected token"은 원인이 다르다. 무엇이 잘못됐는지가 갈린다.

메시지 무엇이 문제 대표 상황
end of JSON input 내용이 조기 종료(빈·잘림) 빈 응답 본문, 빈 문자열, 끊긴 데이터
Unexpected token 형식에 안 맞는 글자 JSON 자리에 HTML(<) 등 잘못된 문자

정리하면, "end of input"은 파싱할 내용이 부족한(끝이 빨리 온) 경우이고, "Unexpected token"은 내용은 있는데 형식이 틀린(엉뚱한 글자가 있는) 경우다. 예를 들어 서버가 JSON 대신 HTML 오류 페이지를 돌려주면 첫 글자 <에서 "Unexpected token" 계열 에러가 나지만, 서버가 아무것도 안 돌려주면 "end of input"이 난다. 정확한 문구는 엔진·버전마다 조금씩 다르지만(최신 크롬은 문제 토큰을 따옴표로 함께 보여준다), "내용 부족이냐 형식 오류냐"라는 구분은 그대로다. 그래서 이 에러를 만나면 "형식"보다 "내용이 있긴 한가"부터 확인하는 게 빠르다.


🧩 자주 나오는 발생 원인 4가지

원인 1 — 빈 응답 본문을 파싱

가장 흔하다. 서버가 본문 없이 응답했는데 await res.json()을 부른 경우다. 특히 204 No Content나 본문이 비는 응답에서 잦다. 파싱할 내용이 없어 곧바로 끝을 만난다.

원인 2 — 빈 문자열을 JSON.parse

JSON.parse("")처럼 빈 문자열을 직접 파싱한 경우다. 변수가 빈 문자열로 초기화됐거나, 어떤 처리 결과가 ""가 되어 그대로 파싱에 넘어가면 이 에러가 난다.

원인 3 — 잘리거나 불완전한 JSON

네트워크가 중간에 끊기거나, 데이터가 완전히 전송되기 전에 파싱해 닫는 괄호가 없는 경우다. 큰 응답이 잘려서 오거나, 스트림을 다 받기 전에 처리하면 생긴다.

원인 4 — 저장소의 빈 값을 파싱

localStorage 등에 빈 문자열("")이 저장돼 있는데 그걸 JSON.parse한 경우다. 참고로 저장된 값이 아예 없어 null이 반환되면 JSON.parse(null)은 null로 처리되어 에러가 안 나지만, 빈 문자열이면 이 에러가 난다.


💻 재현과 진단

전형적인 재현이다. 빈 문자열을 파싱하면 곧바로 이 에러가 난다.

// 빈 문자열 파싱
JSON.parse("");
// ✗ SyntaxError: Unexpected end of JSON input

// 빈 응답 본문에 res.json()
const data = await res.json(); // 본문이 비면 같은 에러

진단의 핵심은 파싱 직전 값을 그대로 보는 것이다. JSON.parse에 넘기기 전 문자열을 찍어 보면 빈 문자열인지, 잘린 조각인지 드러난다. fetch라면 res.json() 대신 res.text()로 먼저 원문을 받아 확인하면 좋다.

// ✓ 원문을 먼저 확인 (text 로 받아 찍어 보기)
const text = await res.text();
console.log("응답 원문:", JSON.stringify(text));
// "" 이면 빈 응답, 잘린 조각이면 불완전 데이터

🛠 해결 방법과 예방

핵심은 두 가지다. 파싱 전에 내용이 있는지 확인하고, 파싱을 try-catch로 감싸 실패에 대비하는 것이다.

상황 해결·예방
빈 응답 status 확인(204 등), text로 받아 비었으면 파싱 건너뛰기
빈 문자열 parse 전 if (text.trim()) 또는 기본값(text || "null") 처리
파싱 실패 일반 JSON.parse를 try-catch로 감싸 안전하게 대비
잘린 데이터 응답을 끝까지 받은 뒤 파싱, 네트워크·서버 로그 확인
저장소 값 getItem 결과가 비었는지 확인 후 기본값으로 대체

가장 안전한 형태는 원문을 먼저 받아 빈 값을 걸러내고, 파싱을 try-catch로 감싸는 것이다. 이렇게 하면 빈 응답이든 잘린 데이터든 앱이 죽지 않고 넘어간다.

// ✓ 빈 값 확인 + try-catch
const text = await res.text();
if (!text.trim()) return null; // 빈·공백 응답이면 파싱 안 함

try {
  const data = JSON.parse(text);
} catch (e) {
  console.error("JSON 파싱 실패:", e.message);
}

한 가지 덧붙이면, 서버 쪽도 챙기면 좋다. 본문이 없는 응답에는 204 No Content를 쓰거나, 최소한 빈 객체({})나 빈 배열([])이라도 내려 주면 클라이언트가 파싱하다 터질 일이 준다. 에러 응답도 JSON 형태로 일관되게 주면, 클라이언트의 방어 코드가 단순해진다.


💬 자주 묻는 질문 5가지

Q1fetch에서 res.json()에 나요.

응답 본문이 비어 있을 때가 흔합니다. res.json()은 내부에서 본문을 JSON으로 파싱하는데, 본문이 비면 빈 문자열을 파싱하다 이 에러가 납니다. 먼저 res.text()로 원문을 받아 비었는지 확인하고, 비었으면 파싱을 건너뛰거나 기본값을 쓰세요. 204 No Content 응답도 이런 경우입니다.

Q2"Unexpected token"과는 뭐가 다른가요?

"end of JSON input"은 내용이 부족해(빈·잘림) 끝이 빨리 온 것이고, "Unexpected token"은 내용은 있는데 형식에 안 맞는 글자를 만난 것입니다. 서버가 JSON 대신 HTML을 주면 첫 글자에서 token 에러가, 아무것도 안 주면 end of input 에러가 납니다.

Q3localStorage 값을 파싱하다 나요.

저장된 값이 빈 문자열("")일 때 납니다. 참고로 키가 아예 없어 getItem이 null을 반환하면 JSON.parse(null)은 문자열 "null"로 처리되어 에러 없이 null이 나옵니다. 그래서 빈 문자열 케이스를 방어해야 합니다. 값이 있는지 확인하고 없으면 기본값을 쓰세요.

Q4가끔씩만 나요. 왜 그런가요?

데이터가 잘려 오는 경우일 수 있습니다. 네트워크가 불안정해 응답이 중간에 끊기거나, 큰 응답을 다 받기 전에 파싱하면 닫는 괄호가 없어 이 에러가 납니다. 응답을 끝까지 받은 뒤 파싱하는지, 서버가 완전한 JSON을 보내는지 확인하세요.

Q5try-catch만 하면 되나요?

에러로 앱이 죽는 건 막지만 근본 해결은 아닙니다. 왜 빈·잘린 데이터가 오는지(빈 응답, 잘못된 API, 네트워크)를 함께 봐야 합니다. try-catch로 안전망을 두되, 원문을 확인해 원인을 고치고, 서버가 본문 없는 응답에 적절한 상태 코드나 빈 객체를 주도록 맞추는 게 좋습니다.


📌 결론

"Unexpected end of JSON input"은 JSON.parse가 완결된 값을 만들기 전에 문자열이 끝나버렸을 때 나는 SyntaxError다. 대부분 빈 응답을 파싱하거나, 빈 문자열·잘린 데이터를 파싱한 경우다. 형식이 틀린 "Unexpected token"과 달리, "내용이 부족하다"는 신호다.

실무 원칙은 다음과 같다.

📭 원문부터 확인한다. 파싱 직전 문자열을 찍어 빈 값인지 잘린 조각인지 본다. fetch는 res.text()로 먼저 받아 확인한다.

🔍 빈 값을 걸러낸다. 파싱 전에 내용이 있는지 확인하고, 빈 응답(204 등)은 파싱을 건너뛰거나 기본값을 쓴다.

🛡 try-catch로 감싼다. JSON.parse를 안전망으로 감싸 앱이 죽지 않게 하되, 빈·잘린 데이터가 오는 근본 원인도 함께 고친다.

end of JSON input 체크리스트

 

01파싱 직전 문자열을 찍어 빈 값·잘린 조각인지 확인.
02fetch는 res.text()로 원문 받아 내용 유무 점검.
03빈 응답(204 등)은 파싱 건너뛰거나 기본값 사용.
04JSON.parse를 try-catch로 감싸 안전망 확보.
05간헐적이면 데이터 잘림(네트워크·미완료 수신) 의심.
06서버는 본문 없는 응답에 204·빈 객체로 일관 처리.

본 글은 자바스크립트 JSON.parse SyntaxError의 일반적 원인과 해결 방법을 정리한 자료다. 코드 수정은 영향 범위를 확인한 뒤 신중히 적용한다.

 

#JavaScript #JSON #JSONparse #UnexpectedendofJSONinput #자바스크립트에러 #SyntaxError #fetch #resjson #빈응답 #trycatch #204NoContent #localStorage #프론트엔드 #JS디버깅 #웹개발

반응형

댓글