PostgreSQL 22P05 오류 원인과 해결 방법 완벽 가이드

22P05
2026년 10월 23일 | DBMS Error 가이드

이 글에서 다루는 내용

22P05 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

22P05 untranslatable character 는?

PostgreSQL 에러 코드 22P05 untranslatable character는 데이터베이스가 특정 문자를 현재 설정된 클라이언트 인코딩 또는 서버 인코딩으로 변환(번역)할 수 없을 때 발생합니다. 예를 들어, 데이터베이스 서버가 UTF-8 인코딩을 사용하고 있는데 클라이언트가 EUC-KR 또는 LATIN1 같은 다른 인코딩 환경에서 해당 인코딩으로 표현할 수 없는 문자를 전송하려 할 때 이 에러가 발생합니다. 이 에러는 특히 다국어 데이터를 처리하거나, 레거시 시스템과 연동하거나, 외부 파일을 임포트할 때 실무에서 빈번하게 마주치게 됩니다.


주요 발생 원인

  • 클라이언트 인코딩과 서버 인코딩 불일치

가장 흔한 원인입니다. PostgreSQL은 클라이언트 인코딩(client_encoding)과 서버(데이터베이스) 인코딩이 다를 때 내부적으로 자동 변환을 시도합니다. 그러나 UTF-8에는 존재하지만 EUC-KR이나 LATIN1에는 매핑되지 않는 문자(예: 이모지, 특수 유니코드 문자)는 변환 자체가 불가능하여 에러가 발생합니다. 예를 들어 서버가 EUC-KR로 설정되어 있고 클라이언트가 UTF-8로 이모지 문자를 포함한 데이터를 삽입하려 하면 이 에러가 발생합니다.

  • COPY 명령 또는 외부 파일 임포트 시 인코딩 미지정

CSV, TSV 같은 외부 파일을 COPY 명령으로 임포트할 때 파일의 실제 인코딩과 PostgreSQL이 기대하는 인코딩이 다르면 이 에러가 발생합니다. 특히 윈도우 환경에서 생성된 파일(CP949, EUC-KR)을 UTF-8 데이터베이스에 인코딩 지정 없이 임포트하거나, 반대로 UTF-8 파일을 EUC-KR 데이터베이스에 임포트하는 경우가 대표적입니다. COPY 명령에 ENCODING 옵션을 생략하면 이 문제가 자주 발생합니다.

  • 애플리케이션 레벨에서 잘못된 인코딩 설정

JDBC, psycopg2, libpq 등 드라이버 또는 ORM을 사용하는 애플리케이션에서 연결 시 client_encoding을 명시적으로 설정하지 않았거나 잘못 설정한 경우입니다. 운영체제의 로케일이 애플리케이션의 기대 인코딩과 다를 때, 드라이버가 OS 로케일을 그대로 사용하면서 PostgreSQL 서버의 인코딩과 충돌하게 됩니다. 이 경우 특정 특수문자가 포함된 데이터 삽입 시에만 간헐적으로 에러가 발생하여 원인 파악이 어렵습니다.


해결 방법

원인 1: 클라이언트 인코딩 불일치 해결

현재 서버와 클라이언트 인코딩을 먼저 확인합니다.

-- 현재 서버 인코딩 및 클라이언트 인코딩 확인
SHOW server_encoding;
SHOW client_encoding;

-- 데이터베이스별 인코딩 확인
SELECT datname, pg_encoding_to_char(encoding) AS encoding
FROM pg_database;

클라이언트 인코딩을 서버 인코딩에 맞게 변경합니다.

-- 세션 수준에서 클라이언트 인코딩을 UTF-8로 변경
SET client_encoding TO 'UTF8';

-- 또는 연결 문자열에서 설정 (psql 사용 시)
-- psql "host=localhost dbname=mydb user=myuser options='-c client_encoding=UTF8'"

-- 변경 확인
SHOW client_encoding;

만약 서버 인코딩을 UTF-8로 새로 구성해야 한다면, 데이터베이스를 새로 생성해야 합니다.

-- UTF-8 인코딩으로 새 데이터베이스 생성
CREATE DATABASE mydb_utf8
  ENCODING 'UTF8'
  LC_COLLATE 'ko_KR.UTF-8'
  LC_CTYPE 'ko_KR.UTF-8'
  TEMPLATE template0;

원인 2: COPY 명령 시 인코딩 명시

-- 잘못된 예 (인코딩 미지정 - 에러 발생 가능)
COPY employees FROM '/data/employees.csv' DELIMITER ',' CSV HEADER;

-- 올바른 예: 파일 인코딩을 명시적으로 지정
COPY employees FROM '/data/employees.csv'
  DELIMITER ','
  CSV HEADER
  ENCODING 'EUC_KR';   -- 파일이 EUC-KR로 저장된 경우

-- UTF-8 파일을 UTF-8 DB에 임포트
COPY employees FROM '/data/employees_utf8.csv'
  DELIMITER ','
  CSV HEADER
  ENCODING 'UTF8';

-- 클라이언트 측에서 \copy 사용 시 (psql)
\copy employees FROM '/local/path/employees.csv' DELIMITER ',' CSV HEADER ENCODING 'EUC_KR';

문제가 되는 문자를 미리 확인하고 싶다면 다음 쿼리를 활용합니다.

-- 번역 불가 문자가 포함된 행을 탐지하는 함수 활용
CREATE OR REPLACE FUNCTION is_encodable(p_text TEXT, p_encoding TEXT)
RETURNS BOOLEAN AS $$
BEGIN
  PERFORM convert(p_text::bytea, 'UTF8', p_encoding);
  RETURN TRUE;
EXCEPTION WHEN others THEN
  RETURN FALSE;
END;
$$ LANGUAGE plpgsql;

-- 테이블에서 EUC-KR로 변환 불가한 행 찾기
SELECT id, name
FROM employees
WHERE NOT is_encodable(name, 'EUC_KR');

원인 3: 애플리케이션 연결 설정 수정

JDBC (Java) 예시:

-- JDBC URL에 characterEncoding 명시
-- jdbc:postgresql://localhost:5432/mydb?characterEncoding=UTF-8

-- PostgreSQL 연결 후 세션 인코딩 강제 설정
SET client_encoding = 'UTF8';

Python psycopg2 예시:

-- 연결 후 즉시 인코딩 설정
-- conn = psycopg2.connect("host=localhost dbname=mydb user=myuser")
-- conn.set_client_encoding('UTF8')

-- PostgreSQL에서 직접 확인
SELECT pg_client_encoding();

postgresql.conf 또는 pg_hba.conf 수준의 기본값 설정:

-- postgresql.conf에서 기본 client_encoding 설정
-- client_encoding = 'UTF8'   -- postgresql.conf 파일에서 설정

-- 또는 ALTER DATABASE로 데이터베이스 기본값 변경
ALTER DATABASE mydb SET client_encoding TO 'UTF8';

-- 특정 사용자에 대해 기본 인코딩 설정
ALTER ROLE myuser SET client_encoding TO 'UTF8';

-- 설정 확인
SELECT rolname, rolconfig
FROM pg_roles
WHERE rolname = 'myuser';

예방 방법

  • 모든 데이터베이스를 UTF-8로 통일하여 생성하고, 연결 인코딩을 명시적으로 관리하세요.

신규 프로젝트에서는 반드시 UTF-8 인코딩으로 데이터베이스를 생성하고, 모든 애플리케이션 연결 시 client_encoding=UTF8을 명시적으로 지정하는 것을 표준 절차로 만들어야 합니다. 이를 통해 다국어 문자, 이모지, 특수 기호 등을 안전하게 저장하고 변환 에러를 원천 차단할 수 있습니다. 레거시 시스템의 경우에도 마이그레이션 시 pg_dump와 pg_restore를 활용해 UTF-8로 전환하는 것을 강력히 권장합니다.

“`sql

— 베스트 프랙티스: UTF-8 DB 생성 템플릿

CREATE DATABASE production_db

ENCODING ‘UTF8’

LC_COLLATE ‘en_US.UTF-8’

LC_CTYPE ‘en_US.UTF-8’

TEMPLATE template0;

— 기본 인코딩 설정 고정

ALTER DATABASE production_db SET client_encoding TO ‘UTF8’;

“`

  • 데이터 입력 전 인코딩 유효성 검사 로직을 애플리케이션 또는 트리거에 추가하세요.

외부 데이터를 받아 저장하는 모든 지점(API 엔드포인트, 파일 업로드, ETL 파이프라인)에서 인코딩 검증 단계를 의무화해야 합니다. PostgreSQL의 convert() 함수나 pg_convert() 함수를 활용하거나, 앞서 작성한 is_encodable() 함수를 트리거에 연결하면 잘못된 인코딩 데이터가 DB에 저장되는 것을 사전에 방지할 수 있습니다.

“`sql

— 인코딩 검증 트리거 예시

CREATE OR REPLACE FUNCTION check_encoding_trigger()

RETURNS TRIGGER AS $$

BEGIN

IF NOT is_encodable(NEW.name, current_setting(‘server_encoding’)) THEN

RAISE EXCEPTION ’22P05: 저장할 수 없는 문자가 포함되어 있습니다: %’, NEW.name;

END IF;

RETURN NEW;

END;

$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_check_encoding

BEFORE INSERT OR UPDATE ON employees

FOR EACH ROW EXECUTE FUNCTION check_encoding_trigger();

“`


관련 에러

  • 22021 character_not_in_repertoire: 현재 문자 레퍼토리(집합)에 없는 문자를 사용할 때 발생합니다. 22P05와 매우 유사하며 함께 검토해야 합니다.
  • 22000 data_exception: 인코딩 변환 실패를 포함한 일반적인 데이터 예외의 부모 에러 클래스입니다.
  • 42704 undefined_object: 존재하지 않는 인코딩 이름을 지정했을 때 발생합니다. ENCODING 'EUC-KR' 대신 ENCODING 'EUC_KR'처럼 PostgreSQL이 인식하는 정확한 인코딩 이름을 사용해야 합니다.
  • 08P01 protocol_violation: 클라이언트 드라이버 레벨에서 인코딩 협상 자체가 실패했을 때 발생할 수 있으며, 22P05와 함께 나타나는 경우가 있습니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기