기술 · 실용 가이드
100·103을 받았는데 curl Empty reply? 최종 응답을 확인하세요
헤더 수신이 곧 완료는 아닙니다. curl 8.5.0의 여섯 가지 대조 실험으로 정보 응답, 정상적인 빈 본문, 오류 52를 구별합니다.

HTTP/1.1 기록에 100 Continue나 103 Early Hints가 있어도 마지막에 curl: (52) Empty reply from server가 나타날 수 있습니다. curl 8.5.0 대조 실험에서 103만 보낸 뒤 연결을 닫자 헤더 71바이트가 저장되고 response_code는 103이었지만 종료 코드는 52였습니다. 헤더 파일이 비어 있지 않거나 코드가 000이 아니라는 사실만으로 최종 응답 도착을 입증할 수 없습니다.
확인할 것은 정보 응답 뒤에 최종 응답이 왔는지, 전송과 기대한 업무 결과가 완료됐는지입니다. 기존 빈 응답 설명이 이미 해결한 기본 사항을 인정하면서 이 구체적인 예외를 보충합니다. 오류 코드만으로 연결을 끊은 구성 요소를 지목하지는 않습니다.
HTTP 상태와 프로세스 종료를 따로 기록
curl --version, 정확한 메서드와 URL, 실행 환경, 프록시 선택, 오류 전문, 시간을 보존하세요. 허가받은 무해한 요청에서 헤더와 본문을 따로 저장합니다. 예: curl -sS -D response.headers -o response.body -w 'code=%{response_code} headers=%{size_header} body=%{size_download}\n' 'https://example.com/'. 직후 POSIX 셸의 rc=$? 같은 방식으로 종료 상태를 저장합니다. 실제 대상 주소로 바꾸고 필요한 인증 정보는 비공개로 보관하세요.
첫 비교에서는 본문을 다른 프로그램에 파이프로 넘기지 말고, 파이프 마지막 명령의 상태를 curl 종료 상태로 오해하지 마세요. write-out HTTP 코드와 프로세스 종료는 다른 정보입니다. 예제에는 --fail이 없으므로 HTTP 4xx/5xx를 완전히 받아 curl이 0으로 끝나도 애플리케이션은 실패할 수 있습니다. 실제 최종 상태와 기대한 내용을 확인해야 합니다.
모든 응답 블록을 순서대로 읽기
RFC 9110은 중간 1xx 응답과 최종 응답을 구별하고, RFC 8297은 103의 헤더 힌트가 최종 응답 헤더를 대신하지 못한다고 규정합니다. 첫 HTTP 상태 줄에서 멈추지 말고 저장된 블록을 모두 읽으세요. 여기서는 100·103 뒤에 연결이 닫힌 경우와 103 뒤에 최종 200이 온 경우를 구분합니다.
프록시 CONNECT 응답이나 리디렉션 이력도 여러 블록을 만들므로 메서드, 상대 주소, 순서를 함께 보존하세요. 앞선 블록을 모두 정보 응답이라고 부르면 안 됩니다. 100 Continue는 요청 진행을 나타내며 업로드의 업무 처리가 완료됐다는 증거가 아닙니다. 103의 Link도 힌트일 뿐, 해당 자원이나 주 요청의 성공을 입증하지 않습니다.
알려진 바이트로 만든 여섯 가지 대조군
Python 3.12.14로 127.0.0.1에서 여섯 가지 합성 응답을 제공했습니다. GET 요청 헤더를 끝까지 읽은 뒤 연결을 정상적으로 닫았습니다. 클라이언트는 Ubuntu curl 8.5.0-2ubuntu10.13이며 --http1.1, --noproxy '*', 연결 제한 2초, 전체 제한 3초를 사용했습니다. 프록시 설정은 로컬 실험을 격리하기 위한 것이며 운영 환경의 필수 프록시를 우회하라는 지시가 아닙니다. TLS, 애플리케이션 서버, 중간 프록시는 시험하지 않았습니다.
응답 바이트가 전혀 없을 때 코드 000, 헤더·본문 0, 종료 52였습니다. 최종 204는 코드 204, 헤더 46바이트, 본문 없음, 종료 0이었고, Content-Length: 0인 최종 200은 코드 200, 헤더 57바이트, 본문 없음, 종료 0이었습니다. 100만 보낸 경우 코드 100, 헤더 25바이트, 종료 52, 103만 보낸 경우 코드 103, 헤더 71바이트, 종료 52였으며 둘 다 본문은 없었습니다. 같은 103 뒤에 최종 200, Content-Length: 2와 본문 OK를 붙이자 코드 200, 헤더 128바이트, 본문 2바이트, 종료 0이 됐습니다. 100 단독 입력은 의도적으로 불완전한 파서 시험용이며 정상적으로 완결된 응답이 아닙니다. 정확한 바이트 수는 이 실험에서 선택한 헤더에만 해당합니다.
최종 응답 전달이 끊긴 경계 찾기
과거 OpenLiteSpeed 커뮤니티 기록에는 클라이언트가 100을 받은 뒤 52로 끝났지만 상위 서버 로그에는 200이 기록된 사례가 있습니다. 실제 질문이 존재한다는 증거이지 현재 제품에 확인된 결함이 있다는 뜻은 아닙니다. 로컬 실험은 클라이언트에 보이는 응답 형태만 재현했으며 해당 배포 구성이나 원인을 재현하지 않았습니다.
관리 권한이 있는 시스템에서 안전한 요청 한 건을 시간과 요청 식별자로 클라이언트·프록시·원본 서버 로그에 연결하세요. 어디서 실제 최종 응답을 기록했고 어디서 하위 연결로 전달했는지 확인합니다. 원본 서버의 200 기록만으로 curl 수신을 증명할 수 없습니다. 실제 빌드를 보존하세요. 별개의 2026년 curl-library 논의는 다른 재현 사례의 52와 56을 다루므로 버전과 실패 형태가 달라도 같은 코드라고 보장하면 안 됩니다.
최종 결과로 수정 검증하기
범위를 좁힌 되돌릴 수 있는 수정 한 가지를 적용한 뒤 실제 경로로 의도한 안전한 요청을 다시 실행하세요. 기대한 최종 상태, 완료된 curl 전송, 올바른 본문 또는 합법적인 본문 부재를 모두 확인해야 합니다. 204에는 원래 응답 내용이 없으며 길이 0을 명시한 200도 유효할 수 있습니다. 둘 다 정보 응답 블록만 받은 경우와는 다릅니다.
업로드나 상태를 바꾸는 API라면 재시도 전에 동작이 이미 수행됐는지 확인하세요. 오류 52는 미수행의 증거가 아닙니다. 인증과 인증서 검증을 유지하고, 오류 숨기기나 무관한 시간 제한 연장, 100·103의 완료 처리로 성공을 만들지 마세요. 담당 경계가 불명확하면 민감 정보를 지운 순서별 응답 블록, 종료 코드, 빌드, 연관 로그를 인계하세요.
