조회수: 23

411 Length Required: Content-Length 추가

411 Length Required는 Content-Length 없는 요청을 서버가 거부한 것입니다. 본문을 버퍼링하고 길이를 재서 다시 보내는 법을 안내합니다. 무료 즉시 HTTP 진단.

내 도메인에 이 문제가 있는지 지금 확인

무료, 가입 불필요. 이 가이드가 다루는 항목을 바로 검사하고 조치 방법을 알려드립니다.

Problem

POSTPUT을 보냈는데 서버가 작업을 하기도 전에 411 Length Required로 튕겨냅니다. 본문은 요청 안에 그대로 있는데 서버가 손도 안 댑니다. 무엇을 보냈는지가 아니라, 무엇을 선언하지 않았는지 — 본문의 크기를, 미리, Content-Length 헤더로 — 를 문제 삼는 것입니다.

Symptoms

  • POST/PUT/PATCH가 애플리케이션 레벨 오류 없이 곧바로 411을 반환합니다.
  • 같은 호출이 curl이나 Postman에서는 되는데 코드에서는 실패합니다(또는 그 반대).
  • 스트리밍/청크 업로드에서 발생합니다 — 파일, 스트림, 제너레이터를 요청 본문에 파이핑할 때.
  • 어떤 클라이언트는 빈 본문 POST(보낼 게 없는 폼 제출이나 웹훅)에서 걸립니다.
  • 실패한 요청이 Content-Length 대신 Transfer-Encoding: chunked를 담고 있습니다.

What This Error Actually Means

HTTP/1.1은 요청 본문을 프레이밍하는 두 방법을 줍니다. Content-Length: 4096을 보내고 정확히 4096바이트를 보내거나 — 고정된, 알려진 크기. 아니면 Transfer-Encoding: chunked를 보내고 본문을 조각으로 스트리밍하며 0바이트 청크로 끝내거나 — 총량을 결코 확정하지 않고. 청크 형태는 얼마나 될지 알기 전에 보내기 시작할 수 있도록 존재합니다.

RFC 9110 §15.5.12는 411을 서버가 두 번째 옵션을 거부하는 것으로 정의합니다: 서버가 “정의된 Content-Length 없이는 요청을 받기를 거부”하는 것. 서버는 한 바이트를 읽기 전에 크기를 알고 싶어 합니다 — 보통 버퍼를 미리 할당하거나, 최대 요청 크기를 강제하거나, 알 수 없는 길이의 스트림을 감당 못 하는 무언가(레거시 핸들러, 엄격한 WAF, 스토리지 API)에 본문을 넘기기 위해서.

중요한 단어는 *정의된(defined)*입니다. 이건 본문이 비었거나 잘못됐다는 게 아닙니다. 서버가 미리 볼 수 없는 길이의 본문을 받기를 거절하는 것입니다. RFC는 처방도 똑같이 명시합니다: 클라이언트는 “유효한 Content-Length 헤더 필드를 추가하면 요청을 반복해도 된다.” 그러니 411은 막다른 길이 아니라 구체적 지시입니다. 그걸 버퍼링하고, 바이트를 세고, 서버에 숫자를 알려주세요.

Top 3 Causes

  1. HTTP 클라이언트가 본문을 청크로 스트리밍한다. 흔한 경우입니다. 많은 HTTP 라이브러리에 파일 객체, 스트림, 제너레이터를 요청 본문으로 넘기면 길이를 계산하려고 전체를 읽는 대신 기본으로 Transfer-Encoding: chunked를 씁니다. Content-Length를 요구하는 서버 상대로는 그런 업로드마다 411이 납니다. 단서: 고정 문자열이나 바이트 버퍼를 넘기면 되고 스트림을 넘기면 실패합니다.
  2. 길이 헤더 없는 빈 본문 POST. 어떤 클라이언트는 보낼 본문이 없으면 Content-Length를 아예 생략합니다 — 맨 폼 제출, 웹훅 핑, 트리거로 쓰는 POST. 엄격한 서버는 “Content-Length 없음, 청크 인코딩 없음”을 “이 요청 본문이 어디서 시작하고 끝나는지 모르겠다”로 읽고 411을 반환합니다. 수정은 헤더 하나: Content-Length: 0.
  3. 청크 요청 본문을 거부하는 엄격한 서버나 미들박스. 구형 IIS 설정, 일부 Java 서블릿 컨테이너, 특정 오브젝트 스토리지 엔드포인트, 하드닝된 WAF는 일부러 청크 요청을 거부합니다 — 버퍼링 전에 한도를 강제하려고 길이를 원하니까요. 당신 클라이언트는 합리적으로 행동하는 것이고, 서버가 스트리밍 경로를 선택 해제하고 411로 그걸 알리는 것뿐입니다.

Diagnose with DechoNet

  • HTTP 진단은 응답이 오리진에서 온 진짜 411인지, 잘못 읽은 400이나 413이 아닌지 확인합니다 — 셋은 늘 뒤섞이고, 수정이 정반대입니다. 정확한 상태 코드와 응답 헤더를 보는 게 클라이언트를 건드리기 전 첫 단계입니다.
  • 진단이 응답 헤더를 보여주니 프록시, CDN, WAF가 경로에 있는지 볼 수 있습니다. 특정 엣지를 통과할 때만 나타나는 411은 오리진이 아니라 미들박스 정책을 가리킵니다 — 업로드 코드를 다시 쓰기 전에 알아둘 가치가 있습니다.

Resolution Checklist

  • 정말 411인지 확인, 413(너무 큼)이나 431(헤더 너무 큼)이 아니라. 수정이 완전히 갈립니다: 411은 길이를 추가, 413은 본문을 축소, 431은 헤더를 다듬는 것.
  • 청크 대신 Content-Length를 보내라. HTTP 클라이언트에서 본문을 완전히 버퍼링하고, 바이트 길이를 재고, 헤더를 명시적으로 설정하세요. 구체적으로: 클라이언트에 스트림을 넘겨 청크되게 하지 말고, 파일/스트림을 문자열이나 바이트 배열로 읽어 들인 뒤 보내세요.
  • 빈 POST면 Content-Length: 0을 설정. 요청에 정말 본문이 없으면 생략하지 말고 명시적 0 길이 헤더로 그렇게 말하세요.
  • 라이브러리의 스트리밍 동작을 확인. 많은 클라이언트가 스트림/제너레이터 본문에 자동으로 청크로 전환합니다. 고정 버퍼를 넘기거나, 길이를 계산해 보내는 클라이언트 옵션을 쓰세요.
  • 서버를 통제하고 이걸 원치 않으면, 청크 요청 본문을 받을지 결정하세요. 일부 스택은 활성화할 수 있고, 대가는 버퍼링 전에 크기 한도를 강제하는 능력을 잃는 것입니다.
  • 같은 경로로 다시 테스트. WAF나 프록시가 411을 강제하는 거라면 직접-오리진 호출이 아니라 실제 엣지 상대로 수정을 검증하세요.

When to Escalate

  • 클라이언트가 이미 올바른 Content-Length를 보내는데도 411이 나면 서비스 앞단의 프록시나 WAF 운영자에게 넘기세요 — 미들박스가 오리진에 닿기 전에 헤더를 벗기거나 재작성할 수 있고, 그쪽 로그만이 그걸 보여줍니다.
  • 서드파티 API가 문서화된 스트리밍 업로드에 411을 반환하면 버그로 단정하기 전에 필수 Content-Length(또는 multipart/resumable 대안)를 문서에서 확인하세요 — 많은 스토리지 API가 일부러 선언된 크기를 요구하고 별도의 청크 업로드 프로토콜을 따로 제공합니다.

관련 도구

관련 가이드

가이드 공유

[Ad] Guide Detail Inline
← 전체 가이드 보기