Post

"Invalid JSON in response body" — n8n과 WordPress를 연동할 때 반드시 의심해봐야 할 곳

"Invalid JSON in response body" — n8n과 WordPress를 연동할 때 반드시 의심해봐야 할 곳

며칠 전, 크립토 뉴스 자동 발행 워크플로우(가나투데이) 운영 중에 갑자기 낯선 에러를 만났습니다. 썸네일 이미지를 WordPress에 업로드하는 단계에서 Invalid JSON in response body라는 메시지와 함께 실행이 멈춘 것입니다. 30개 넘는 버그를 잡아온 자동화 파이프라인이었는데, 이번엔 조금 다른 종류의 함정이었습니다. 오늘은 그 진단 과정을 그대로 기록해봅니다.

자동화 파이프라인은 한 단계가 막히면 뒤의 모든 단계가 도미노처럼 멈춥니다. 특히 이번처럼 “파일 업로드는 성공했는데 다음 노드로 못 넘어가는” 애매한 상황은, 원인을 잘못 짚으면 엉뚱한 곳만 몇 시간씩 헤매기 쉽습니다. 그래서 이번엔 문제를 해결한 결과뿐 아니라, 무엇을 먼저 의심했고 왜 틀렸는지까지 순서대로 남겨둡니다. 같은 에러 메시지를 만난 분이 검색으로 이 글을 찾아왔을 때, 삽질 시간을 줄이는 데 도움이 되길 바라는 마음입니다.

증상 — 파일은 올라갔는데 에러가 난다

n8n의 HTTP Request 노드로 POST /wp-json/wp/v2/media를 호출했는데, 응답을 JSON으로 파싱하는 순간 에러가 났습니다. 처음엔 흔한 원인부터 의심했습니다.

  • Application Password가 만료됐나?
  • 보안 플러그인이 요청을 막았나?
  • 파일 용량이 서버 제한을 넘었나?

그런데 이상한 점이 있었습니다. WordPress 미디어 라이브러리를 확인해보니 파일은 정상적으로 업로드되어 있었습니다. 요청은 성공했는데, n8n이 응답을 못 읽는 상황이었던 겁니다. “서버가 요청을 거부한 게 아니라, 응답 자체가 이상하다”는 신호였습니다.

첫 번째 진단 — Response Format을 Text로 바꿔서 원문을 본다

JSON 파싱 에러가 나면 가장 먼저 할 일은, 파싱을 시도하지 말고 날것 그대로의 응답을 보는 것입니다. n8n의 HTTP Request 노드에는 Options → Response → Response Format을 Text로 바꾸는 옵션이 있습니다. 이렇게 하면 파싱 실패 없이 서버가 실제로 뭘 돌려줬는지 그대로 확인할 수 있습니다.

결과는 예상 밖이었습니다.

1
HTTPS 인식됨: on{"id":238,"date":"2026-08-18T04:14:08", ...

정상 JSON은 반드시 {로 시작해야 하는데, 그 앞에 알 수 없는 한글 텍스트가 붙어 있었습니다. WordPress REST API가 정상적으로 게시물 데이터를 생성해서 돌려주고는 있지만, 그 앞에 뭔가가 끼어들어 응답을 오염시키고 있다는 게 확실해졌습니다.

오답 노트 — 스니펫과 플러그인을 먼저 뒤졌다

가장 먼저 의심한 건 Code Snippets 플러그인이었습니다. 활성화된 스니펫이 하나 있었는데(404 페이지 리다이렉트 처리 코드), 확인해보니 template_redirect 훅에 걸려 있었고 REST API 요청 경로에는 아예 관여하지 않는 코드였습니다. 무죄.

다음으로 활성 플러그인 목록(Code Snippets, LiteSpeed Cache, Rank Math SEO, Site Kit, 호스팅어 관련 플러그인들)을 훑었지만, 전부 잘 알려진 대형 플러그인이라 한글로 된 커스텀 디버그 문구가 들어있을 가능성은 낮았습니다.

여기서 놓치기 쉬운 함정이 하나 있습니다. 일반 페이지에서는 이 문제가 눈에 잘 안 띈다는 점입니다. 브라우저로 사이트를 열면 이상한 텍스트가 아주 잠깐 스치듯 보였다가, 뒤이어 로드되는 정상 HTML에 덮여 사라집니다. 반면 REST API 응답은 순수 텍스트/JSON만 오기 때문에, 이걸 덮어줄 후속 콘텐츠가 없어서 오염된 텍스트가 그대로 노출됩니다. 같은 원인이 증상만 다르게 나타난 겁니다.

진짜 원인 — wp-config.php

범위를 좁혀나간 끝에 다다른 곳은 워드프레스에서 가장 먼저 실행되는 파일, wp-config.php였습니다. 열어보니 define('WP_CACHE', true); 바로 다음 줄에 이런 코드가 남아 있었습니다.

1
2
3
4
5
if (!empty($_SERVER['HTTPS'])) {
    echo "HTTPS 인식됨: " . $_SERVER['HTTPS'];
} else {
    echo "HTTPS 인식 안 됨 — 이게 원인입니다";
}

예전에 Application Password 문제를 해결하면서 HTTPS 인식 여부를 확인하려고 임시로 넣었던 디버그 코드가 지워지지 않고 남아 있었던 것입니다. wp-config.php는 DB 연결보다도 먼저, 그리고 모든 요청(일반 페이지든 REST API든 관리자 화면이든)마다 무조건 실행되는 파일이라, 이 다섯 줄이 조용히 모든 응답 맨 앞에 텍스트를 찍고 있었습니다.

해결과 검증

해당 블록을 통째로 삭제하고, 브라우저에서 직접 확인했습니다.

1
https://ganatoday.com/wp-json/wp/v2/posts?per_page=1

응답이 HTTPS 인식됨 없이 [로 바로 시작하는 순수 JSON으로 돌아온 것을 확인한 뒤, n8n의 관련 노드들(WordPress 포스팅, 썸네일 업로드, 대표 이미지 지정)의 Response Format을 다시 JSON으로 원복하고 전체 워크플로우를 재실행해 정상 작동을 확인했습니다.

이번 사례에서 얻은 체크리스트

  1. “Invalid JSON in response body” 에러 = 파싱 실패이지 요청 실패가 아니다. 실제 데이터는 정상 생성됐을 수 있으니, 먼저 서버 쪽 결과부터 확인한다.
  2. Response Format을 Text로 바꿔 원문을 보는 것이 가장 빠른 진단법이다. 추측하지 말고 실제로 뭐가 오는지 눈으로 확인한다.
  3. HTML 페이지에서 안 보인다고 문제가 없는 게 아니다. JSON/API 응답에서만 드러나는 오염 문제도 있다.
  4. 원인을 좁혀갈 때는 실행 순서를 기준으로 삼는다. 플러그인 → mu-plugins → 테마 functions.php → wp-config.php 순으로, 더 일찍 실행되는 파일일수록 모든 응답에 영향을 미친다.
  5. 디버그 코드는 그때그때 지운다. 문제를 해결한 뒤 임시로 넣은 echo/print 문을 남겨두면, 몇 주 뒤 완전히 다른 증상으로 재발한다.
  6. 의심 순서를 정해두면 헤매는 시간이 줄어든다. 플러그인 → mu-plugins → 테마 functions.php → wp-config.php. 이 순서를 미리 알고 있었다면 스니펫과 플러그인 목록을 뒤지는 데 쓴 시간을 절반 이상 아꼈을 것입니다.

왜 이런 문제가 반복될 수 있는가

이번 사례가 특히 기억에 남는 이유는, 원인이 n8n도 WordPress 플러그인도 아니라 서버 설정 파일에 남은 흔적이었기 때문입니다. 자동화 도구를 다루다 보면 문제가 생겼을 때 자연스레 자동화 도구부터 의심하게 되는데, 실제로는 그보다 훨씬 앞단, 즉 데이터가 만들어지는 원천 쪽에 원인이 있는 경우가 적지 않습니다. 특히 이번처럼 눈에 보이는 화면(브라우저)에서는 증상이 스치듯 지나가 버리고, API 응답처럼 가공되지 않은 원본을 봐야만 드러나는 문제는 더더욱 그렇습니다. 정기적으로 REST API 엔드포인트를 브라우저로 직접 열어 원본 응답을 확인해보는 습관을 들이면, 이런 유형의 문제를 훨씬 빨리 잡아낼 수 있습니다.

자동화 파이프라인이 복잡해질수록, 에러의 원인이 항상 자동화 도구(n8n) 안에 있는 건 아니라는 걸 다시 한번 배웠습니다. 이번엔 워드프레스 설정 파일 다섯 줄이 범인이었습니다. 비슷한 “Invalid JSON” 에러를 만나신 분들께 조금이나마 도움이 되길 바랍니다.

— 다메섹 교수

This post is licensed under CC BY 4.0 by the author.