WordPress 플러그인 충돌 사이트 먹통 복구 방법 (White Screen 해결)

사이트에 접속했더니 하얀 화면만 나온다. 어제까지 잘 되던 사이트가 갑자기 먹통이 된 거다. 관리자 페이지(wp-admin)도 열리지 않고, 500 에러만 반복되는 상황. 이런 일이 보통 새벽에 터진다. 자동 업데이트가 돌아간 직후, 혹은 플러그인 하나를 무심코 업데이트한 뒤에. 나도 운영 중인 워드프레스 사이트에서 두 번이나 이 상황을 겪었는데, 처음엔 호스팅 문제인 줄 알고 업체에 문의부터 했다. 결론부터 말하면, 대부분의 원인은 플러그인 충돌이고 복구 방법도 정해져 있다.

White Screen of Death(WSOD)가 발생하는 원인

워드프레스에서 하얀 화면(WSOD)이나 500 Internal Server Error가 뜨는 원인은 크게 네 가지로 나뉜다. 내 경험상 80% 이상은 플러그인 관련 문제였다.

플러그인 업데이트 후 충돌

가장 흔한 케이스이다. 플러그인 A가 업데이트되면서 플러그인 B와 같은 함수명을 사용하거나, 워드프레스 코어 API의 deprecated된 함수를 호출하면서 Fatal Error가 발생한다. 특히 캐시 플러그인(W3 Total Cache, WP Super Cache)과 보안 플러그인(Wordfence, iThemes Security)이 동시에 업데이트될 때 충돌이 잦다.

PHP 버전 비호환

호스팅 업체가 PHP 버전을 올린 경우에도 동일한 증상이 나타난다. PHP 7.4에서 정상 동작하던 플러그인이 PHP 8.0 이상에서 null 파라미터 처리 방식이 달라져서 에러를 뿜는 경우가 대표적이다. 실제로 PHP 8.1 업그레이드 이후 Contact Form 7이 일시적으로 문제를 일으킨 적이 있었다.

PHP 메모리 한도 초과

공유 호스팅에서 자주 발생한다. 플러그인이 많아지면 로딩 시 필요한 메모리가 증가하는데, 기본 설정인 64MB나 128MB로는 부족할 수 있다. 특히 WooCommerce + 다국어 플러그인 + 페이지 빌더 조합은 메모리를 상당히 잡아먹다.

테마와 플러그인 간 충돌

테마가 자체적으로 포함한 기능과 플러그인이 제공하는 기능이 겹칠 때 발생한다. 예를 들어 Elementor 같은 페이지 빌더를 사용하면서 테마에 내장된 빌더 기능이 활성화되어 있으면 JavaScript 충돌이나 PHP Fatal Error가 생길 수 있다.

wp-config.php 디버그 모드로 원인 파악하기

하얀 화면만 뜨면 뭐가 문제인지 알 수가 없다. 가장 먼저 할 일은 디버그 모드를 켜서 실제 에러 메시지를 확인하는 것이다. FTP 클라이언트(FileZilla 등)나 호스팅 파일 매니저로 wp-config.php 파일을 열어서 아래 설정을 추가한다.

// wp-config.php 파일에서 아래 라인을 찾아 수정하거나 추가
// "That's all, stop editing!" 주석 위에 넣어야 합니다

// 디버그 모드 활성화
define( 'WP_DEBUG', true );

// 에러를 화면에 표시
define( 'WP_DEBUG_DISPLAY', true );

// 에러를 /wp-content/debug.log 파일에 기록
define( 'WP_DEBUG_LOG', true );

// PHP 메모리 한도 증가 (메모리 부족 의심 시)
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );

설정 후 사이트를 새로고침하면 하얀 화면 대신 구체적인 에러 메시지가 표시된다. 보통 아래와 같은 형태로 나온다.

Fatal error: Uncaught Error: Call to undefined function
wp_some_function() in /var/www/html/wp-content/plugins/
problematic-plugin/includes/class-main.php on line 142

PHP Fatal error: Allowed memory size of 67108864 bytes
exhausted (tried to allocate 4096 bytes) in /var/www/html/
wp-content/plugins/heavy-plugin/core/loader.php on line 58

Fatal error: Cannot redeclare some_helper_function()
(previously declared in /var/www/html/wp-content/plugins/
plugin-a/helpers.php:23) in /var/www/html/wp-content/plugins/
plugin-b/utils.php on line 31

에러 메시지에 나오는 파일 경로를 보면 어떤 플러그인이 문제인지 바로 알 수 있다. /wp-content/plugins/플러그인-폴더명/ 경로를 주목하면 된다. 솔직히 말하면, 이 단계에서 원인을 특정할 수 있는 경우가 절반 이상이다.

FTP로 플러그인 폴더 비활성화하여 복구하기

wp-admin에 접근 자체가 안 되는 상황이라면 FTP를 통해 직접 플러그인을 비활성화해야 한다. 이 방법이 가장 확실하고 빠르다.

모든 플러그인 한꺼번에 비활성화

FTP로 서버에 접속한 뒤, /wp-content/ 디렉토리 안에 있는 plugins 폴더의 이름을 변경한다. 이렇게 하면 워드프레스가 플러그인 폴더를 인식하지 못해 모든 플러그인이 비활성화된다.

# FTP 또는 SSH 접속 후 실행

# 1단계: plugins 폴더 이름 변경 (전체 비활성화)
cd /var/www/html/wp-content/
mv plugins plugins_backup

# 2단계: 빈 plugins 폴더 생성 (워드프레스가 정상 동작하려면 필요)
mkdir plugins

# 3단계: 사이트 접속 확인 후, 문제 없으면 플러그인을 하나씩 복원
# 원본 폴더에서 플러그인을 하나씩 옮겨가며 테스트
mv plugins_backup/akismet plugins/akismet
# 사이트 확인 → 정상이면 다음 플러그인
mv plugins_backup/contact-form-7 plugins/contact-form-7
# 사이트 확인 → 에러 발생 시 이 플러그인이 원인

# 4단계: 문제 플러그인 제외하고 나머지 모두 복원
mv plugins_backup/* plugins/

# 5단계: 빈 백업 폴더 삭제
rmdir plugins_backup

이 과정을 거치면 어떤 플러그인이 문제를 일으키는지 정확하게 파악할 수 있다. 좀 귀찮더라도 하나씩 옮기는 것이 핵심이다. 두세 개씩 한꺼번에 옮기면 충돌 조합을 놓칠 수 있거든.

특정 플러그인만 비활성화

디버그 로그에서 원인 플러그인을 이미 파악한 경우에는 해당 플러그인 폴더만 이름을 바꾸면 된다. 예를 들어 wordfence가 문제라면 wordfencewordfence_disabled로 변경한다.

WP-CLI를 활용한 복구

SSH 접근이 가능한 환경이라면 WP-CLI가 가장 효율적인 도구이다. 한 줄 명령어로 플러그인을 관리할 수 있어서, 서버를 직접 관리하는 분들에게 강력히 추천한다.

# WP-CLI 설치 (아직 없다면)
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

# 워드프레스 루트 디렉토리로 이동
cd /var/www/html

# 현재 활성화된 플러그인 목록 확인
wp plugin list --status=active --path=/var/www/html

# 특정 플러그인 비활성화 (원인을 아는 경우)
wp plugin deactivate wordfence --path=/var/www/html

# 모든 플러그인 한꺼번에 비활성화
wp plugin deactivate --all --path=/var/www/html

# 비활성화 후 사이트 접근 테스트
wp eval 'echo "사이트 정상 동작 확인";' --path=/var/www/html

# 플러그인을 하나씩 활성화하며 원인 찾기
wp plugin activate akismet --path=/var/www/html
wp plugin activate contact-form-7 --path=/var/www/html
# ... 에러 발생 시 해당 플러그인이 원인

# 문제 플러그인 삭제 후 재설치 (버전 충돌 시)
wp plugin delete problematic-plugin --path=/var/www/html
wp plugin install problematic-plugin --version=3.2.1 --path=/var/www/html
wp plugin activate problematic-plugin --path=/var/www/html

# 캐시 정리 (캐시 플러그인 관련 충돌 시)
wp cache flush --path=/var/www/html
wp transient delete --all --path=/var/www/html

WP-CLI의 장점은 에러가 발생해도 터미널에서 바로 에러 메시지를 확인할 수 있다는 점이다. 웹 브라우저로 확인할 필요 없이 명령어 결과로 정상 여부를 판단할 수 있으니 작업 속도가 확실히 빨라진다.

phpMyAdmin으로 플러그인 강제 비활성화

FTP도 안 되고 SSH도 없는 최악의 상황이라면, 호스팅 패널에서 제공하는 phpMyAdmin을 사용해 데이터베이스를 직접 수정할 수 있다. 다만 이 방법은 DB를 직접 건드리는 것이므로 반드시 백업을 먼저 하자.

phpMyAdmin에 접속한 뒤 wp_options 테이블을 열고, option_name 컬럼에서 active_plugins 행을 찾다. 이 값은 PHP의 직렬화(serialized) 형식으로 활성 플러그인 목록을 저장하고 있다.

-- 현재 활성 플러그인 확인
SELECT option_value FROM wp_options
WHERE option_name = 'active_plugins';

-- 결과 예시 (serialized 형태):
-- a:5:{i:0;s:19:"akismet/akismet.php";i:1;s:36:
-- "contact-form-7/wp-contact-form-7.php";...}

-- 모든 플러그인 비활성화 (값을 빈 배열로 변경)
UPDATE wp_options
SET option_value = 'a:0:{}'
WHERE option_name = 'active_plugins';

-- 테이블 접두사가 다를 수 있으니 확인
-- wp-config.php의 $table_prefix 값을 확인하자
-- 예: $table_prefix = 'wp_blog_' 인 경우
SELECT option_value FROM wp_blog_options
WHERE option_name = 'active_plugins';

active_plugins의 값을 a:0:{}로 변경하면 모든 플러그인이 비활성화된다. 이후 wp-admin에 접속해서 필요한 플러그인을 하나씩 활성화하면 된다. 정말 마지막 수단이라고 생각하면 되고, 가능하면 FTP나 WP-CLI를 먼저 시도하는 게 안전하다.

충돌 원인 플러그인 특정하기

플러그인이 20개, 30개 설치되어 있으면 하나씩 테스트하는 것도 일이다. 좀 더 체계적으로 접근하는 방법이 있다.

이진 탐색(Binary Search) 방법

플러그인이 많을 때 하나씩 테스트하면 시간이 너무 오래 걸린다. 절반씩 나눠서 테스트하면 훨씬 빠르게 원인을 찾을 수 있다.

  1. 전체 플러그인을 절반으로 나눈다 (A그룹, B그룹)
  2. A그룹만 활성화하고 사이트 확인
  3. 에러가 발생하면 A그룹에 원인이 있음 → A그룹을 다시 절반으로 나눠서 반복
  4. 에러가 안 나면 B그룹에 원인이 있음 → B그룹을 다시 절반으로 나눠서 반복
  5. 범위가 좁혀지면 개별 플러그인 단위로 테스트

이 방법으로 30개 플러그인도 5~6회 테스트 만에 원인을 찾을 수 있다. 프로그래밍의 이진 탐색 알고리즘과 동일한 원리이다.

충돌이 잦은 플러그인 조합

경험적으로 아래 조합에서 충돌이 자주 발생한다. 이 조합에 해당하는 플러그인을 먼저 의심하면 시간을 절약할 수 있다.

플러그인 카테고리 충돌 상대 증상
캐시 플러그인 (W3TC, WP Super Cache) 보안 플러그인 (Wordfence) 방화벽 규칙이 캐시된 페이지와 충돌
페이지 빌더 (Elementor) 최적화 플러그인 (Autoptimize) JS/CSS 결합 시 레이아웃 깨짐
SEO 플러그인 (Yoast) 다른 SEO 플러그인 (Rank Math) 메타 태그 중복, sitemap 충돌
WooCommerce 다국어 플러그인 (WPML) 결제 프로세스 오류, 번역 누락
이미지 최적화 (Smush) CDN 플러그인 (Cloudflare) 이미지 로딩 실패, 무한 리다이렉트

재발 방지를 위한 운영 전략

복구에 성공했다면, 같은 문제가 반복되지 않도록 운영 방식을 바꿔야 한다. 사후 대응보다 사전 예방이 훨씬 편하다. 한 번 새벽에 장애 대응을 해보면 예방의 소중함을 뼈저리게 느끼게 된다.

스테이징 환경 구축

운영 사이트에서 바로 업데이트하지 말자. 동일한 환경의 스테이징(테스트) 사이트를 만들어서 먼저 업데이트를 적용하고, 문제가 없는지 확인한 후에 운영 사이트에 반영한다. WP Staging 같은 플러그인을 사용하면 스테이징 환경을 쉽게 만들 수 있고, 관리형 호스팅(Kinsta, WP Engine 등)은 기본적으로 스테이징 기능을 제공한다.

플러그인 업데이트 원칙

여러 플러그인을 한꺼번에 업데이트하면 문제가 생겼을 때 원인을 찾기 어렵다. 아래 원칙을 지키면 장애 위험을 크게 줄일 수 있다.

  • 한 번에 하나씩 업데이트하고, 각 업데이트 후 사이트 정상 동작 확인
  • 자동 업데이트 비활성화 — 주요 플러그인은 수동으로 관리
  • 업데이트 전 백업 — UpdraftPlus 등으로 전체 백업 후 진행
  • 변경 로그 확인 — 업데이트 내용에 Breaking Change가 있는지 확인
  • PHP 버전 호환성 확인 — 플러그인 페이지에서 “Tested up to” 버전 확인

에러 로깅 상시화

디버그 모드를 상시로 켜두되, 화면 출력은 끄고 로그 파일에만 기록하도록 설정한다. 이렇게 하면 방문자에게는 에러가 보이지 않으면서도 관리자는 문제를 조기에 발견할 수 있다.

// wp-config.php — 운영 환경 권장 설정

// 디버그 활성화하되 화면에는 표시하지 않음
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', false );

// 로그 파일에만 기록 (/wp-content/debug.log)
define( 'WP_DEBUG_LOG', true );

// 에러 표시 완전히 차단 (보안 목적)
@ini_set( 'display_errors', 0 );

// 선택: 로그 파일 경로를 커스텀으로 지정
// define( 'WP_DEBUG_LOG', '/var/log/wordpress/debug.log' );

생성된 debug.log 파일을 주기적으로 확인하거나, 로그 모니터링 도구(예: WP Mail Log, Error Log Monitor 플러그인)를 연동하면 문제가 커지기 전에 대응할 수 있다. 나는 debug.log를 주 1회 확인하는 습관을 들인 이후로 갑작스러운 장애를 사전에 막은 적이 두 번 있었다.

긴급 복구 체크리스트

마지막으로, 장애 발생 시 순서대로 따라갈 수 있는 체크리스트를 정리한다. 당황하면 순서가 뒤섞이기 쉬우니 이 목록을 즐겨찾기 해두시면 도움이 된다.

  1. wp-config.php에서 WP_DEBUG 활성화 → 에러 메시지 확인
  2. 에러 메시지에 특정 플러그인 경로가 있으면 해당 플러그인 비활성화
  3. 원인 불명확 시 FTP로 plugins 폴더 이름 변경 → 전체 비활성화
  4. 사이트 복구 확인 후 플러그인을 하나씩 활성화하며 원인 특정
  5. 원인 플러그인 발견 시: 이전 버전으로 롤백하거나 대체 플러그인 검토
  6. 복구 완료 후 WP_DEBUG_DISPLAY를 false로 변경 (운영 환경 보안)
  7. 향후 재발 방지를 위해 스테이징 환경 및 백업 체계 점검

플러그인 충돌은 워드프레스를 운영하는 한 언제든 발생할 수 있다. 중요한 건 당황하지 않고 체계적으로 접근하는 것이다. 디버그 모드로 원인을 파악하고, FTP나 WP-CLI로 빠르게 복구하고, 스테이징 환경으로 예방하는 이 세 단계만 기억하면 대부분의 상황에 대응할 수 있다.