워드프레스 이미지 업로드 "HTTP 오류": 원인을 진짜로 찾아내는 판단 트리
확인 한 번으로 워드프레스 이미지 업로드 HTTP 오류의 실제 원인을 가려내고, 방화벽·PHP 메모리·post_max_size·Imagick 중 맞는 갈래만 고칩니다.
게시됨
“HTTP 오류”는 원인이 아닙니다. 미디어 업로더가 파일을 서버에 보냈지만 성공으로 해석할 수 없는 응답을 받았다고 실토하는 문구이고, 서로 무관한 최소 여섯 가지 실패가 똑같은 이 한 줄을 만들어 냅니다. 그 사이를 추측으로 헤매기 때문에, 진짜 문제가 방화벽 규칙인 사이트에서 오후 내내 upload_max_filesize만 올리고 앉아 있게 됩니다.
가장 빠른 탈출로는, 여섯 원인을 두 덩어리로 쪼개는 관찰 한 번, 그리고 갈래마다 확인 한 가지입니다.
먼저: 실제 응답을 읽는다
브라우저 개발자 도구를 열고 네트워크 탭으로 간 다음 파일을 다시 올리세요. async-upload.php 요청을 지켜봅니다. 거기서 돌아오는 것이 곧 진단입니다.
| 보이는 것 | 의미 | 이동 |
|---|---|---|
| HTML 본문과 함께 403 또는 406 | 방화벽이나 mod_security가 요청을 거부 | 갈래 A |
| 500, 빈 응답, 또는 잘린 본문 | 처리 도중 PHP가 죽었거나 메모리 부족 | 갈래 B |
| 413 | 요청 본문이 서버 한도를 초과 | 갈래 C |
| 200인데 본문이 온전한 JSON이 아님 | 플러그인이나 테마가 응답보다 먼저 출력을 냄 | 갈래 D |
| 요청이 끝나지 않거나 타임아웃 | 실행 시간 한도, 보통 큰 파일에서 발생 | 갈래 B |
이 한 번의 확인이 인터넷에 떠도는 조언 대부분을 걸러 줍니다. 브라우저 도구를 쓸 수 없다면 wp-config.php에서 로깅부터 켜세요.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
업로드를 재현한 뒤 wp-content/debug.log를 읽습니다. 치명적 오류 한 줄이 어느 갈래인지 대놓고 알려 줍니다. 문장이 빽빽하다면 오류 로그 해석기에 붙여 넣으세요. 흔한 치명적 오류 패턴을 실제로 무엇이 깨졌는지로 연결해 줍니다.
갈래 A — 방화벽 또는 mod_security 규칙
본문에 HTML 페이지가 담긴 403은 요청이 WordPress까지 아예 닿지 못했다는 뜻입니다. 그 앞단의 무언가, 즉 mod_security, Cloudflare, Wordfence, Sucuri, 혹은 호스팅 자체 규칙이 그 POST를 악성으로 판단한 것입니다.
확인 방법은 보안 플러그인을 잠시 비활성화하고 다시 올려 보는 것입니다. 변화가 없다면 규칙은 서버 단에 있고, 실패한 업로드 시각으로 mod_security 감사 로그를 확인해 달라고 호스팅에 요청해야 합니다. 해당 규칙 ID만 예외 처리해 줄 수 있습니다.
이 대목에서 만나게 될 조언에 대해서는 스스로 정직해야 합니다. .htaccess에 이걸 넣으라는 코드 조각들,
SecFilterEngine Off
SecFilterScanPOST Off
이건 사실상 멸종한 mod_security 1.x를 대상으로 합니다. 요즘 서버에서는 아무 일도 하지 않거나, 사이트를 더 망치는 500을 던집니다. 현대의 mod_security는 SecRuleEngine을 쓰고, 대부분의 관리형 호스팅은 디렉터리 단위 재정의 자체를 막아 둡니다. 붙여 넣지 말고 호스팅에 물어보세요.
갈래 B — PHP 메모리 또는 실행 한도
가장 흔한 갈래이자 신호가 가장 분명한 갈래입니다. 간헐적으로 실패합니다. 같은 파일이 세 번째 시도에 올라가거나, 2MB 사진은 실패하는데 6MB PDF는 멀쩡히 통과합니다. 고정된 설정 한도는 매번 똑같이 실패합니다. 메모리 실패는 그렇지 않은데, 쓸 수 있는 양이 서버가 그 순간 무슨 일을 하고 있느냐에 달렸기 때문입니다.
왜 하필 이미지인가. WordPress는 파일을 저장만 하는 게 아니라 원시 픽셀로 풀어헤쳐 중간 크기들을 전부 만들어 냅니다. medium_large, add_image_size로 등록한 모든 크기, 쇼핑몰을 운영한다면 woocommerce_thumbnail, 그리고 이미지가 big_image_size_threshold를 넘으면 -scaled 사본까지요. 1200만 화소 JPEG은 디스크에서 몇 MB지만 메모리에서는 약 48MB이고, 리사이즈 버퍼는 아직 계산에도 넣지 않았습니다. 128MB 한도는 순식간에 사라집니다.
wp-config.php의 “편집 중단” 줄 위에서 올리세요.
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
실제 대가는 이렇습니다. WP_MEMORY_LIMIT은 PHP 자체가 허용하는 값을 넘지 못합니다. 호스팅이 memory_limit을 128M로 묶어 두었다면 이 상수는 장식일 뿐입니다. 내가 적은 값이 아니라 도구 → 사이트 상태 → 정보 → 서버에서 실제 값을 확인하세요. PHP 자체 한도가 천장이라면 호스팅만이 그것을 올릴 수 있습니다.
갈래 C — 파일 크기와 요청 한도
도구 → 사이트 상태 → 정보 → 미디어 처리에서 실제 숫자를 확인하세요. 중요한 설정은 둘인데 사람들은 늘 하나만 건드립니다.
upload_max_filesize— 파일 하나의 상한.post_max_size— 요청 본문 전체의 상한.
POST 전체가 post_max_size를 넘으면 PHP는 WordPress 코드가 실행되기도 전에 요청을 버립니다. 돌려줄 것이 존재하지 않으니 업로더는 해석 불가능한 응답을 받고 “HTTP 오류”라고 말합니다. post_max_size는 언제나 upload_max_filesize보다 넉넉히 커야 합니다.
알아 둘 만한 단서가 하나 있습니다. 파일이 upload_max_filesize만 넘긴 경우에는 보통 업로더가 브라우저 단에서 잡아내며 최대 업로드 크기를 초과했다는, 훨씬 명확한 메시지를 보여 줍니다. 그러니 아무 설명 없는 “HTTP 오류”는 모두가 제일 먼저 올리는 그 설정보다 post_max_size나 갈래 B를 가리키는 경우가 더 많습니다.
어디서 바꾸느냐는 서버 구성에 따라 다릅니다. mod_php를 쓰는 Apache라면 .htaccess가 먹힙니다.
php_value upload_max_filesize 64M
php_value post_max_size 128M
요즘 호스팅 대부분인 PHP-FPM, LiteSpeed, NGINX에서는 이 줄들이 아무 일도 하지 않거나 500을 던집니다. 대신 호스팅의 PHP 설정 패널이나 .user.ini 파일을 쓰세요. NGINX는 자체적으로 client_max_body_size도 적용하는데, 이건 호스팅만 올릴 수 있습니다.
갈래 D — 이미지 편집 라이브러리 (Imagick vs GD)
WordPress는 해당 PHP 확장이 있으면 ImageMagick을 우선 쓰고, 없으면 GD로 넘어갑니다. 공용 호스팅에서는 ImageMagick이 문제인 경우가 잦습니다. 정책 설정 파일이 작업당 메모리, 디스크, 처리 면적을 제한하는데, 리사이즈가 그중 하나에 걸리면 프로세스가 쓸 만한 메시지 없이 죽습니다. 보통 큰 이미지에서만 나고 작은 것은 잘 되는데, 겉보기에 갈래 B 같지만 아닙니다.
가설을 검증하려면 GD를 강제하세요.
add_filter( 'wp_image_editors', function ( $editors ) {
return array( 'WP_Image_Editor_GD' );
} );
functions.php나 작은 mu-plugin에 넣고 업로드를 다시 시도한 뒤, 달라지는 게 없으면 지우면 됩니다.
정직한 맞바꿈은 이렇습니다. GD가 무조건 낫지는 않습니다. 압축을 푼 비트맵 전체를 PHP 메모리에 들고 있기 때문에, 아주 큰 파일에서는 PHP 할당 바깥에서 일부 작업을 하는 ImageMagick이라면 성공했을 상황에서 memory_limit에 부딪힐 수 있습니다. 한 실패를 다른 실패로 바꾸는 셈이 되기도 합니다. 해결책이기 이전에 진단 도구로 쓰세요.
갈래 E — 업로드 디렉터리 권한
관리형 호스팅에서는 드물지만, 이전 작업 직후나 서버를 수동으로 옮긴 뒤에는 흔합니다. wp-content/uploads에 웹 서버 사용자의 쓰기 권한이 없거나, 새로 만들어진 연/월 하위 폴더가 엉뚱한 소유자를 물려받으면 쓰기가 실패합니다.
ls -ld wp-content/uploads
ls -ld wp-content/uploads/2026/07
디렉터리는 보통 755여야 하고 PHP가 실행되는 사용자 소유여야 합니다. 어느 게시판이 시켰다고 777로 두지는 마세요. 폴더를 서버의 모든 계정이 쓸 수 있게 만들어 증상만 없애는 것이고, 공용 호스팅에서는 실질적인 노출입니다.
갈래 F — 파일 이름
목록에서 가장 값싼 확인이니, 가능성이 제일 낮더라도 일찍 해 보세요. 파일 이름을 소문자 영문, 숫자, 하이픈만 쓰도록 바꾸고(악센트, 아포스트로피, 앰퍼샌드, #, 비라틴 문자 금지) 다시 올려 봅니다. 특수문자가 이따금 보안 규칙에 걸리거나 인코딩이 어긋난 파일 시스템에서 깨집니다. 10초면 지워지는 갈래입니다.
하지 말아야 할 것
플러그인 전부 끄기부터 시작하지 마세요. 파괴적인데다 갈래 A와 갈래 D만 검증합니다. 네트워크 응답이 5초 만에 더 많은 것을 알려 줍니다.
출처 불명의 .htaccess 핸들러 줄을 넣지 마세요. 돌아다니는 SetHandler나 AddHandler 지시문 조각들은 특정 호스팅의 PHP 구성을 전제로 합니다. 구성이 다르면 500과 함께 사이트 전체가 내려갑니다.
“다시 시도하니 됐다”를 해결로 받아들이지 마세요. 간헐적 성공은 갈래 B의 서명이고, 서버가 바빠지거나 누가 더 큰 파일을 올리는 순간 그대로 돌아옵니다.
그래도 안 될 때
응답이 깔끔한 200에 유효한 JSON인데도 업로드가 실패한다면, 파일이 도착한 이후에 깨지는 것입니다. 보통 첨부 처리 체인에 훅을 건 플러그인이 치명적 오류를 내거나, 최적화 플러그인이 외부 서비스로 자체 요청을 보냈다가 타임아웃되는 경우입니다. WP_DEBUG_LOG를 켜고 재현한 뒤, 나온 치명적 오류를 오류 로그 해석기에 돌려 어느 파일과 어느 훅이 실제 책임인지 확인하세요.
FAQ
질문
워드프레스에 이미지를 올릴 때 나오는 HTTP 오류는 무슨 뜻인가요?
브라우저 업로더가 파일을 서버로 보냈는데, 성공 응답으로 해석할 수 없는 무언가가 돌아왔다는 뜻입니다. 이 문구는 원인이 아니라 증상을 말합니다. PHP 프로세스 중단, 방화벽 차단, 403, 빈 응답이 전부 똑같은 이 한 줄로 나타납니다.
같은 이미지가 어떤 때는 올라가고 어떤 때는 실패하는 이유는 뭔가요?
간헐적 실패는 설정 한도보다 메모리나 CPU 고갈을 가리키는 경우가 거의 전부입니다. 큰 사진을 리사이즈하려면 순간적으로 메모리가 몰리는데, 공용 호스팅에서는 서버 부하에 따라 쓸 수 있는 양이 달라집니다. post_max_size 같은 고정 한도는 매번 똑같이 실패합니다.
워드프레스를 Imagick에서 GD로 바꾸면 HTTP 오류가 해결되나요?
특정 갈래에서만, 때때로 해결됩니다. 공용 호스팅의 ImageMagick은 정책 파일이나 낮은 리소스 한도로 묶여 있는 경우가 많아 GD가 성공하는 곳에서 실패합니다. 다만 GD는 아주 큰 파일에서 메모리를 더 쓰기 때문에, 바꾸면 메모리 때문에 나던 실패가 오히려 심해질 수 있습니다.
호스팅 방화벽이 업로드를 막고 있는지 어떻게 확인하나요?
브라우저 네트워크 도구를 열고 파일을 올린 뒤 async-upload.php의 응답 상태 코드를 보세요. HTML 본문과 함께 403이나 406이 오면 웹 애플리케이션 방화벽이나 mod_security 규칙이 요청을 거부한 것입니다. 500이거나 응답이 비어 있으면 PHP가 죽은 쪽입니다.
upload_max_filesize를 올리면 HTTP 오류가 해결되나요?
파일이 실제로 한도를 넘을 때만 그렇고, 보통은 post_max_size가 더 중요합니다. 요청 본문 전체가 post_max_size보다 크면 PHP가 WordPress 실행 전에 요청을 버리고, 업로더는 아무것도 받지 못합니다. 한쪽만 올리면 실패는 그대로 남습니다.
파일 이름 때문에 워드프레스 HTTP 오류가 날 수도 있나요?
네, 가장 드문 갈래이긴 합니다. 악센트 문자, 아포스트로피, 앰퍼샌드, 비라틴 문자는 보안 규칙에 걸리거나 인코딩이 어긋난 파일 시스템에서 경로를 깨뜨릴 수 있습니다. 소문자 영문·숫자·하이픈으로 바꿔 보는 데는 비용이 들지 않고, 10초면 이 갈래를 지울 수 있습니다.