2026년 08월 21일 | DBMS Error 가이드
이 글에서 다루는 내용
22032 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
22032 invalid json text 는?
PostgreSQL 에러 코드 22032는 invalid json text로, JSON 데이터를 파싱하거나 처리하는 과정에서 입력된 문자열이 유효한 JSON 형식이 아닐 때 발생합니다. 주로 json 또는 jsonb 타입의 컬럼에 데이터를 삽입하거나 JSON 관련 함수를 호출할 때 입력값이 JSON 스펙(RFC 7159)을 준수하지 않는 경우에 트리거됩니다. 애플리케이션 레이어에서 JSON 직렬화 오류, 수동 문자열 조합 실수, 또는 외부 시스템에서 전달된 비정형 데이터가 원인이 되는 경우가 많아 운영 환경에서 빈번하게 마주치는 에러 중 하나입니다.
주요 발생 원인
1. 잘못된 JSON 문법 (따옴표, 괄호, 콤마 오류)
가장 흔한 원인으로, JSON은 키가 반드시 큰따옴표(")로 감싸져야 하며 값의 끝에 불필요한 콤마가 있거나 중괄호/대괄호의 짝이 맞지 않으면 파싱에 실패합니다. 예를 들어 작은따옴표로 키를 감싸거나({'key': 'value'}), 마지막 요소 뒤에 콤마를 붙이는 실수({"key": "value",})는 SQL에서는 허용되지 않는 전형적인 오류입니다.
2. NULL 바이트 또는 제어 문자 포함
JSON 문자열 내부에 null 바이트(\u0000) 또는 허용되지 않는 제어 문자(0x00~0x1F)가 포함된 경우, PostgreSQL의 JSON 파서가 이를 유효하지 않은 입력으로 간주하고 에러를 발생시킵니다. 이는 외부 API 응답, 파일 업로드, 레거시 시스템과의 데이터 연동 시 특히 자주 발생하며, 눈에 보이지 않는 문자이기 때문에 디버깅이 어렵습니다.
3. 빈 문자열 또는 NULL이 아닌 불완전한 JSON 조각 입력
애플리케이션에서 JSON 생성 로직이 실패하거나 미완성된 경우, "", {, [1,2, 처럼 불완전한 JSON 조각이 데이터베이스로 전달될 수 있습니다. 빈 문자열은 유효한 JSON이 아니며, 중간에 잘린 JSON 역시 파서가 처리할 수 없어 동일한 에러를 유발합니다.
해결 방법
원인 1: 잘못된 JSON 문법 수정
삽입 전에 json_valid() 또는 캐스팅 시도를 통해 유효성을 검사하는 방법을 활용하세요.
-- 에러 발생 예시: 작은따옴표 사용, 마지막 콤마
INSERT INTO events (payload) VALUES ("{'event': 'click',}");
-- ERROR: invalid input syntax for type json
-- 올바른 JSON 형식으로 수정
INSERT INTO events (payload) VALUES ('{"event": "click"}');
-- 기존 잘못된 데이터 확인 (텍스트 컬럼에 저장된 경우)
SELECT id, raw_json
FROM staging_table
WHERE raw_json IS NOT NULL
AND raw_json !~ '^[\s]*[\{\[]'; -- 기본적인 구조 사전 점검
-- json_typeof를 이용한 유효성 간접 확인 (변환 가능 여부 테스트)
DO $$
DECLARE
test_input TEXT := '{"key": "value"}';
BEGIN
PERFORM test_input::json;
RAISE NOTICE 'Valid JSON';
EXCEPTION WHEN invalid_text_representation THEN
RAISE NOTICE 'Invalid JSON: %', test_input;
END;
$$;
원인 2: NULL 바이트 및 제어 문자 제거
데이터 정제 후 삽입하거나, 삽입 전 전처리 함수를 통해 문제 문자를 제거하세요.
-- NULL 바이트 제거 후 JSON으로 캐스팅
INSERT INTO events (payload)
SELECT replace(raw_json, chr(0), '')::jsonb
FROM staging_table
WHERE raw_json IS NOT NULL;
-- 제어 문자 범위 전체 제거 (정규식 활용)
UPDATE staging_table
SET raw_json = regexp_replace(raw_json, '[\x00-\x1F\x7F]', '', 'g')
WHERE raw_json ~ '[\x00-\x1F\x7F]';
-- 안전한 변환 함수 생성 (운영 환경 권장)
CREATE OR REPLACE FUNCTION safe_to_jsonb(input TEXT)
RETURNS JSONB AS $$
BEGIN
RETURN replace(input, chr(0), '')::jsonb;
EXCEPTION WHEN OTHERS THEN
RETURN NULL; -- 변환 실패 시 NULL 반환
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- 활용 예시
SELECT safe_to_jsonb('{"name": "Alice"}');
SELECT safe_to_jsonb('invalid json'); -- NULL 반환
원인 3: 불완전한 JSON 조각 필터링 및 복구
스테이징 테이블에서 유효하지 않은 데이터를 격리하고 처리하는 패턴을 도입하세요.
-- 유효한 JSON만 선택적으로 이관
INSERT INTO events (payload)
SELECT raw_json::jsonb
FROM staging_table
WHERE raw_json IS NOT NULL
AND length(raw_json) > 2 -- 최소 길이 필터
AND (
(left(trim(raw_json), 1) = '{' AND right(trim(raw_json), 1) = '}')
OR
(left(trim(raw_json), 1) = '[' AND right(trim(raw_json), 1) = ']')
);
-- 실패한 데이터 별도 테이블로 분리 보관
CREATE TABLE json_parse_errors (
id SERIAL PRIMARY KEY,
raw_input TEXT,
error_message TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
DO $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT id, raw_json FROM staging_table LOOP
BEGIN
INSERT INTO events (payload) VALUES (rec.raw_json::jsonb);
EXCEPTION WHEN OTHERS THEN
INSERT INTO json_parse_errors (raw_input, error_message)
VALUES (rec.raw_json, SQLERRM);
END;
END LOOP;
END;
$$;
예방 방법
1. 애플리케이션 레이어에서 JSON 유효성 검증 후 전송
데이터베이스에 JSON을 삽입하기 전, 애플리케이션 코드(Python의 json.dumps(), Java의 ObjectMapper, JavaScript의 JSON.stringify())를 통해 반드시 직렬화된 JSON만 전달하도록 설계하세요. 수동 문자열 조합 방식으로 JSON을 만드는 것은 극력 피하고, 검증된 라이브러리를 통해 생성된 JSON만 사용하는 것이 원칙입니다. 또한 CHECK 제약 조건을 활용하면 컬럼 레벨에서 이중 방어가 가능합니다.
-- CHECK 제약 조건으로 컬럼 레벨 방어 (text 컬럼 사용 시)
ALTER TABLE events
ADD CONSTRAINT chk_payload_valid_json
CHECK (payload::jsonb IS NOT NULL);
-- 단, jsonb 타입 자체가 자동으로 유효성 검사를 수행하므로
-- jsonb 컬럼 사용이 가장 권장되는 방법입니다.
2. 스테이징 테이블 + 변환 검증 파이프라인 도입
외부 시스템이나 파일로부터 JSON 데이터를 수신할 때는, 반드시 스테이징(임시) 테이블에 TEXT 타입으로 먼저 적재한 뒤 유효성 검사를 거쳐 실제 테이블로 이관하는 ETL 파이프라인을 구성하세요. 이 방식은 파싱 에러가 발생해도 원본 데이터를 보존할 수 있으며, 오류 데이터를 별도 관리하여 추후 수동 복구나 재처리가 가능한 구조를 만들어줍니다.
관련 에러
22P02(invalid_text_representation): JSON 외에도 UUID, 정수형 등 다른 타입의 입력 변환 실패 시 발생하며,22032와 함께 묶여서 나타나는 경우가 많습니다.22000(data_exception): JSON 관련 함수(json_extract_path,jsonb_set등)에서 구조적으로 잘못된 경로나 연산을 수행할 때 발생할 수 있습니다.42804(datatype_mismatch): JSON 컬럼에 전혀 다른 타입의 값을 삽입하려 할 때 발생하며,22032와 혼동하지 않도록 주의가 필요합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.