브라우저가 API로 직접 보내던 업로드를 웹 서버의 BFF가 전달하도록 바꾼다고 하자. 이전 API 프록시의 제한은 충분해도 새 웹 프록시가 먼저 요청을 거절할 수 있다. SSR 자체보다 업로드 요청에 추가된 홉을 확인해야 하는 상황이다.

이 글의 질문은 업로드 요청을 처음 413으로 거절한 계층은 어디인가다. multipart 업로드와 Nginx, Beanstalk 배포를 예로 들어 요청 경로와 실제 적용 설정을 함께 추적한다.

작은 파일 하나로 경로부터 확인한다

설정을 바꾸기 전에 허용될 만큼 작은 요청에 요청 ID를 붙이고 웹 프록시, BFF, API 프록시, API 로그에 같은 ID가 있는지 확인한다. 이어서 제한보다 큰 요청을 보내 어느 지점부터 로그가 사라지는지 비교한다.

기존 경로가 브라우저 → API 프록시 → API → 저장소였다면 변경된 경로는 브라우저 → 웹 프록시 → BFF → API 프록시 → API → 저장소일 수 있다. 실제 라우팅을 확인한 뒤 경로를 적는다. 렌더링 방식이 바뀌었어도 업로드 경로가 같다면 다른 원인을 찾아야 한다.

웹 프록시가 큰 multipart 요청을 413으로 거절하면 BFF와 API·저장소에는 요청이 도달하지 않는 예제

그림은 웹 프록시가 먼저 거절하는 경우다. BFF 파서나 API의 제한이 더 낮으면 거절 지점이 뒤로 이동한다. 응답의 모양은 단서일 뿐, 첫 거절 계층은 access·error 로그와 다음 계층의 요청 유무로 확인한다.

파일 크기와 요청 본문 크기를 구분한다

multipart 본문에는 파일 외에도 boundary와 필드가 들어간다. 파일 여러 개를 보내면 합계가 적용되고 base64로 감싸면 전송 크기가 더 커질 수 있다. 파일 하나의 용량만 기준으로 프록시 한도를 정하면 경계값에서 요청이 실패할 수 있다.

Nginx의 client_max_body_size는 요청 본문 최대 크기이며 http, server, location에 둘 수 있다. 기본값은 1m이고 초과하면 413을 반환한다. client_body_buffer_size는 읽기 버퍼 크기이므로 최대 허용량을 바꾸는 설정과 구분한다. Nginx 본문 크기 지시어.

기존 업로드 location에 다음 제한을 적용한다고 하자.

location /api/uploads/ {
    client_max_body_size 12m;
    proxy_pass http://upload_backend;
}

12m는 요청 전체 크기를 설명하는 예제 값이다. 별도 location을 그대로 추가하면 기존 라우팅과 충돌하거나 우선순위가 달라질 수 있으므로 실제 업로드 location을 찾아 수정한다. 애플리케이션의 파일별·요청별 제한과 제품 정책도 함께 맞춘다. 무제한 설정은 업로드 정책을 대신하지 않는다.

저장소의 설정 파일과 실행 설정은 다르다

Beanstalk의 Linux 플랫폼에서는 source bundle의 .platform/nginx/conf.d/*.conf가 HTTP 블록을 확장하고, .platform/nginx/conf.d/elasticbeanstalk/*.conf가 기본 server 블록을 확장한다. 같은 지시어라도 include 위치에 맞춰야 한다. Beanstalk 프록시 확장 위치를 실제 플랫폼 버전과 대조한다.

검증은 저장소에 파일이 있는지에서 끝나지 않는다. 업로드한 번들에 들어갔는지, 인스턴스에 배치됐는지, Nginx가 해당 파일을 읽는지 순서대로 확인한다.

nginx -t
nginx -T

-t는 문법과 참조 파일을 검사한다. -T는 같은 검사에 더해 읽은 설정을 출력하므로 활성 location과 최종 제한을 찾을 수 있다. 출력에는 민감한 설정이 섞일 수 있어 공유 전 확인한다. 문법 성공은 새 설정으로 요청이 처리된다는 증거와 구분한다. Nginx 실행 옵션.

전달 업로드와 직접 업로드를 선택하는 기준

BFF를 통한 업로드는 서버에서 접근 제어와 후처리 흐름을 모으기 쉽지만, 각 프록시의 본문 제한과 전달 메모리·타임아웃을 관리해야 한다. 큰 파일이 빈번하다면 S3 presigned URL로 브라우저가 저장소에 직접 보내는 방식도 검토한다. S3 presigned URL은 특정 작업을 제한된 기간 동안 허용하는 수단이다.

직접 업로드에서도 서버는 업로드 권한, 객체 키 범위, 만료와 업로드 후 실제 객체 검증을 맡아야 한다. 413 조사와 S3 IAM·서명 오류는 실패 지점과 응답 의미가 다르다. 서로 다른 과거 문제를 하나의 원인으로 묶지 않는다.

마지막 확인은 실제 배포 경로에서 정책 한도 아래, 경계 근처, 한도 위의 요청을 비교하는 일이다. 파일 합계와 multipart 오버헤드를 포함하고 각 계층의 응답을 확인한다. 업로드 경로에 프록시가 추가된 상황이라면 처음 거절한 계층을 찾은 뒤 그 위치의 적용 설정을 확인하는 순서가 유효하다.