본문으로 건너뛰기
snowflake검색
운영과 비용

적재 오류 트러블슈팅 (COPY, Snowpipe, 파일 형식, 권한)

COPY INTO 와 Snowpipe 적재가 실패하거나 조용히 건너뛸 때 보는 순서와, 열 수 불일치, 날짜와 숫자 형식, 인코딩, 이미 적재된 파일, 스토리지 통합 권한, 이벤트 알림 누락, 반정형 데이터 크기 같은 사례를 증상, 원인, 해결 순서로 정리합니다.

트러블슈팅COPY INTOSnowpipe적재 오류파일 형식스토리지 통합VALIDATE2026-10 기준, 약 9분

먼저 볼 것

적재 문제는 크게 세 가지입니다. 파일을 못 읽음(권한, 경로), 파일을 읽었지만 행이 거부됨(형식), 파일이 아예 처리 대상이 아님(이미 적재됨, 알림 누락). 어느 쪽인지 먼저 가릅니다.

-- 최근 적재 기록 (COPY 와 Snowpipe 모두, 14일)
SELECT file_name, status, row_count, row_parsed, first_error_message,
       first_error_line_number, first_error_column_name, last_load_time
FROM TABLE(INFORMATION_SCHEMA.COPY_HISTORY(
  TABLE_NAME => 'RAW.EVENTS',
  START_TIME => DATEADD(hour, -24, CURRENT_TIMESTAMP())))
ORDER BY last_load_time DESC;

-- 적재 전에 오류만 미리 보기
COPY INTO raw.events FROM @raw.s3_events
  FILE_FORMAT = (FORMAT_NAME = 'raw.csv_fmt')
  VALIDATION_MODE = RETURN_ERRORS;

-- 방금 실행한 COPY 의 거부 행
SELECT * FROM TABLE(VALIDATE(raw.events, JOB_ID => '_last'));

기본 문법과 옵션은 COPY INTO, 자동 적재는 Snowpipe 문서에 있습니다.

사례 1. 열 수가 맞지 않습니다

  • 증상: "Number of columns in file (12) does not match that of the corresponding table (11)" 오류가 납니다.
  • 원인: 원본 시스템이 열을 추가했거나, 값 안의 구분자(쉼표)가 따옴표로 감싸지지 않았습니다.
  • 해결: 따옴표 문제라면 파일 형식에 FIELD_OPTIONALLY_ENCLOSED_BY = '"' 를 넣습니다. 열이 늘어난 것이라면 테이블에 열을 추가하거나 ERROR_ON_COLUMN_COUNT_MISMATCH = FALSE 를 검토합니다. 열 이름으로 맞추려면 헤더를 읽는 PARSE_HEADER = TRUE 와 MATCH_BY_COLUMN_NAME 을 씁니다.

사례 2. 날짜, 숫자 형식 오류

  • 증상: "Date '2026/10/01' is not recognized" 또는 "Numeric value '1,234' is not recognized" 가 납니다.
  • 원인: 파일의 날짜, 숫자 표기가 Snowflake 기본 형식과 다릅니다.
  • 해결: 파일 형식에 DATE_FORMAT = 'YYYY/MM/DD', TIMESTAMP_FORMAT 을 지정합니다. 천 단위 쉼표 같은 표기는 COPY 의 변환 쿼리에서 TO_NUMBER($3, '9,999,999') 처럼 처리하거나, 문자열로 받은 뒤 변환합니다.

사례 3. 한글이 깨지거나 인코딩 오류가 납니다

  • 증상: "Invalid UTF8 detected in string" 오류가 나거나 적재된 한글이 깨집니다.
  • 원인: 파일이 UTF-8 이 아니라 CP949(EUC-KR) 입니다. 국내 레거시 시스템 내보내기에서 흔합니다.
  • 해결: CSV 파일 형식에 원본 인코딩을 지정합니다. EUC-KR 은 ENCODING = 'EUCKR', 확장 완성형(CP949 계열)은 ENCODING = 'WINDOWS949' 입니다. 깨진 바이트를 대체 문자로 바꾸고 계속하려면 REPLACE_INVALID_CHARACTERS = TRUE 를 씁니다.

사례 4. COPY 가 성공했는데 0 행입니다

  • 증상: COPY 결과가 "Copy executed with 0 files processed" 이고 데이터가 들어오지 않습니다.
  • 원인: 같은 파일을 64일 안에 이미 적재해 적재 메타데이터가 건너뛰었습니다. 또는 PATTERN 이 파일 이름과 맞지 않습니다.
  • 해결: COPY_HISTORY 에서 그 파일이 이미 LOADED 인지 봅니다. 정말 다시 넣어야 한다면 FORCE = TRUE 를 쓰되 중복을 주의합니다. 패턴은 LIST @stage PATTERN = '...' 로 먼저 확인합니다.

주의 FORCE = TRUE 와 PURGE = FALSE 조합을 정기 작업에 넣으면 같은 파일이 매번 다시 들어갑니다. 재적재는 한 번만 수동으로 실행합니다.

사례 5. 스토리지 통합 권한 오류

  • 증상: "Failed to access remote file: access denied" 또는 "Insufficient privileges to operate on integration" 이 납니다.
  • 원인: 클라우드 쪽 IAM 역할(또는 Azure 동의, GCS 서비스 계정 권한)이 버킷 경로를 허용하지 않거나, 신뢰 정책의 외부 ID 가 바뀌었거나, Snowflake 역할에 통합 USAGE 가 없습니다.
  • 해결:
DESC INTEGRATION s3_int;   -- STORAGE_AWS_IAM_USER_ARN, STORAGE_AWS_EXTERNAL_ID 확인
GRANT USAGE ON INTEGRATION s3_int TO ROLE loader;

AWS IAM 역할의 신뢰 정책에 위 사용자 ARN 과 외부 ID 가 그대로 들어 있는지, 권한 정책에 s3:GetObject, s3:ListBucket 이 해당 경로로 있는지 확인합니다. 통합을 CREATE OR REPLACE 로 다시 만들면 외부 ID 가 바뀌니 신뢰 정책도 갱신해야 합니다.

사례 6. Snowpipe 가 새 파일을 못 봅니다

  • 증상: 버킷에 파일이 쌓이는데 AUTO_INGEST 파이프가 적재하지 않습니다.
  • 원인: 버킷 이벤트 알림이 파이프의 알림 채널(SQS 등)로 오지 않거나, 이벤트 필터 경로가 파이프 경로와 다르거나, 파이프가 일시 중지 상태입니다.
  • 해결:
SELECT SYSTEM$PIPE_STATUS('raw.events_pipe');   -- executionState, pendingFileCount, lastReceivedMessageTimestamp
SHOW PIPES LIKE 'EVENTS_PIPE';                  -- notification_channel
ALTER PIPE raw.events_pipe REFRESH;             -- 최근 7일 안의 누락 파일 다시 큐에 넣기

lastReceivedMessageTimestamp 가 오래되었다면 알림 설정 문제입니다. 같은 버킷 접두사에 이벤트 알림을 둘 이상 걸 수 없는 제약 때문에 기존 알림과 충돌하는 경우도 흔합니다.

사례 7. 반정형 데이터가 너무 큽니다

  • 증상: JSON 적재에서 "Max LOB size exceeded" 류의 오류가 납니다.
  • 원인: 파일 전체가 하나의 큰 JSON 배열이라 한 행으로 읽히거나, 한 문서가 VARIANT 크기 한도를 넘었습니다.
  • 해결: 파일 형식에 STRIP_OUTER_ARRAY = TRUE 를 지정해 배열 요소를 행으로 나눕니다. 그래도 크면 원본에서 문서를 쪼개거나 큰 필드는 따로 저장합니다. 한도는 공식 문서의 데이터 형식 표를 확인합니다. 반정형 데이터 문서를 참고합니다.

사례 8. Parquet 적재 후 값이 NULL 입니다

  • 증상: Parquet 파일을 적재했는데 일부 열이 모두 NULL 입니다.
  • 원인: MATCH_BY_COLUMN_NAME 을 쓸 때 열 이름 대소문자가 맞지 않거나, 변환 쿼리에서 $1:column 경로 이름을 틀렸습니다.
  • 해결: MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE 를 쓰고, INFER_SCHEMA 로 파일의 실제 열 이름과 형식을 확인합니다.
SELECT * FROM TABLE(INFER_SCHEMA(
  LOCATION => '@raw.s3_events/2026/10/',
  FILE_FORMAT => 'raw.parquet_fmt'));

오류 처리 옵션 고르기

ON_ERROR동작맞는 곳
ABORT_STATEMENT (COPY 기본)하나라도 오류면 전체 중단정확성이 중요한 배치
CONTINUE오류 행만 건너뜀일부 손실을 허용하는 로그
SKIP_FILE (Snowpipe 기본)오류가 있는 파일 통째로 건너뜀파일 단위 재처리
SKIP_FILE_, SKIP_FILE_%오류가 n 개 또는 n% 넘으면 파일 건너뜀약간의 오류 허용

건너뛴 행과 파일은 반드시 따로 기록하고 알림을 겁니다. 조용히 사라진 데이터가 가장 찾기 어렵습니다.

공식 문서

이 문서에서