워드프레스 업데이트 후 “치명적인 오류” 해결기: 로그 한 줄로 원인 찾기
워드프레스 치명적인 오류 메시지를 내 블로그에서 직접 보게 될 줄은 몰랐다. 9월 29일, 워드프레스 코어와 플러그인을 한꺼번에 업데이트하고 나서 글을 열었더니 화면에 “이 웹사이트에 치명적인 오류가 있습니다.” 한 줄만 덩그러니 떠 있었다.
이상한 점은 홈 화면은 멀쩡했다는 것이다. 카테고리 목록도, 고정 페이지도 잘 열렸다. 그런데 개별 글만 전부 열리지 않았다. 블로그에서 가장 중요한 페이지가 몽땅 죽은 셈이다. 이번 글에서는 그날 원인을 찾고 복구한 과정을 순서대로 정리해 보려고 한다. 같은 메시지를 보고 당황한 누군가에게 도움이 되면 좋겠다.

증상부터 정확히 나누자
워드프레스 치명적인 오류 메시지는 어떤 문제든 똑같이 보여 준다. 그래서 메시지 자체로는 아무것도 알 수 없다. 대신 어디가 되고 어디가 안 되는지를 먼저 나누면 범위가 확 줄어든다.
- 홈, 카테고리 목록, 고정 페이지(About) → 정상
- 모든 개별 글 → 500 오류, “치명적인 오류” 메시지
- 관리자 화면 → 정상
개별 글에서만 실행되는 코드는 생각보다 적다. 글 템플릿(single.php), 그리고 댓글이나 목차처럼 글 화면에만 붙는 플러그인 정도다. 이 단계에서 이미 용의자가 몇 개로 좁혀진다.
워드프레스 치명적인 오류 원인 찾는 순서
1. 관리자 이메일부터 확인
워드프레스는 치명적인 오류가 나면 관리자 이메일로 “사이트에 기술적 문제가 발생했습니다”라는 메일을 보낸다. 여기에 문제를 일으킨 플러그인이나 테마의 이름, 그리고 복구 모드 링크가 들어 있다. 메일 설정이 되어 있다면 이게 가장 빠르다.
2. 서버 에러 로그 확인
메일이 없거나 정보가 부족하면 서버 로그를 본다. Apache라면 보통 /var/log/apache2/error.log, Nginx라면 /var/log/nginx/error.log에 PHP 치명적 오류가 남는다. 로그 위치가 헷갈린다면 리눅스 로그 파일 위치 정리 글을 참고하자.
여기서 한 번 헛걸음을 했다. 처음에 tail로 마지막 오류만 봤더니 7월 날짜의 엉뚱한 오류가 나왔다. 봇이 위젯 파일에 직접 접속해서 남긴, 이번 장애와 상관없는 기록이었다. 반드시 오늘 날짜로 걸러서 보자.
# 오늘 수정된 에러 로그 파일 찾기
sudo find /var/log -name "*error*" -newermt "2026-09-29"
# 오늘 날짜의 치명적 오류만 보기
sudo grep "Sep 29" /var/log/apache2/error.log | grep -i "fatal" | tail -5그래도 안 보이면 로그를 켜 둔 채로 글 페이지를 새로고침하는 방법이 가장 확실하다.
sudo tail -f /var/log/apache2/error.log3. 로그 한 줄에서 원인 읽기
드디어 찾은 오늘 날짜의 로그는 이랬다. (경로 외의 정보는 줄였다.)
PHP Fatal error: Uncaught Error: Call to undefined method
FluentComments\App\Hooks\Handlers\CommentsHandler::encryptDecrypt()
in /var/www/html/wp-content/mu-plugins/itinfo-comments-template.php:34읽는 법은 간단하다. in 뒤의 경로가 범인의 위치다. /themes/면 테마, /plugins/플러그인명/이면 그 플러그인, 내 경우처럼 /mu-plugins/면 직접 넣은 커스텀 코드다. 오류 내용은 “존재하지 않는 메서드를 호출했다”는 뜻이다.
원인 : 플러그인 내부 함수에 기댄 커스텀 코드
이 블로그는 댓글에 Fluent Comments 플러그인을 쓰고 있다. 닉네임 기본값, 삭제용 비밀번호, 한글 문구 같은 커스터마이징은 플러그인 파일을 직접 고치지 않으려고 mu-plugins에 따로 만들어 두었다. 업데이트로 덮어써지지 않게 하려는 나름의 배려였다.
문제는 그 커스텀 코드가 플러그인 내부 함수(encryptDecrypt())를 직접 부르고 있었다는 점이다. 이번 업데이트(2.1.1)에서 이 함수가 사라졌고, 존재하지 않는 함수를 부르는 순간 PHP가 멈췄다. 결국 이번 워드프레스 치명적인 오류 원인은 이 한 줄이었다. 이 코드가 글 화면의 헤더를 만드는 단계에서 실행되니, 개별 글만 전부 죽은 것이다. 처음에 나눴던 증상과 정확히 맞아떨어진다.
워드프레스 치명적인 오류 응급 처치에서 놓친 것들
첫 번째 수정, 그리고 두 번째 오류
급한 대로 함수가 있을 때만 부르도록 방어 코드를 넣었다.
$handler = new \FluentComments\App\Hooks\Handlers\CommentsHandler();
// 함수가 없으면 건너뛴다 (업데이트로 사라진 경우 사이트 전체가 멈추는 것을 방지)
if (!is_callable([$handler, 'encryptDecrypt'])) {
return;
}그런데 여전히 오류였다. 같은 함수를 댓글 폼 파일에서도 부르고 있었던 것이다. 이번엔 워드프레스 치명적인 오류 화면이 글 본문 아래에 붙어서 나왔는데, 레이아웃이 700px로 확 좁아져 있었다. 워드프레스 오류 화면의 CSS(body { max-width: 700px })가 페이지 전체에 적용된 탓이다. 화면이 이상하게 좁아졌다면 페이지 중간에서 치명적 오류가 난 것일 수 있다.
당장 사이트부터 살려야 할 때는 문제의 파일을 잠시 꺼 두는 방법도 있다. 지우는 게 아니라 이름만 바꾸는 것이라 언제든 되돌릴 수 있다.
sudo mv wp-content/mu-plugins/문제파일.php wp-content/mu-plugins/문제파일.php.off페이지는 열리는데 댓글이 안 달린다
두 번째 수정까지 마치자 글은 정상으로 열렸다. 여기서 끝냈다면 큰일 날 뻔했다. 확인해 보니 댓글 등록 버튼을 눌러도 아무 일도 일어나지 않았다. 오류 메시지도 없이 조용히 실패하고 있었다.
새 버전의 Fluent Comments는 댓글 영역 전체를 자바스크립트 앱이 직접 그리고 전송하는 구조로 바뀌어 있었다. 예전 PHP 템플릿을 복사해 만든 내 커스텀 폼은 새 앱과 연결되지 않으니, 겉모습만 있고 아무도 처리하지 않는 폼이 된 것이다. 500 오류보다 오히려 이쪽이 더 위험하다. 방문자는 댓글이 사라진 줄도 모르기 때문이다.
근본 해결 : 공식 훅으로 다시 만들기
같은 워드프레스 치명적인 오류 상황을 반복하지 않도록 결국 커스텀 코드를 새 버전 구조에 맞춰 다시 만들었다. 이번에는 원칙을 하나 정했다. 플러그인 내부 클래스와 함수는 절대 직접 부르지 않고, 플러그인이 공식으로 제공하는 훅만 쓴다. 다행히 새 버전은 확장용 훅을 문서화해 두었다(Fluent Comments 저장소).
fluent_comments/form_fields: 댓글 폼에 입력칸 추가 (삭제용 비밀번호)fluent_comments/validate_submission: 등록 전 검증 (비밀번호 필수)fluent_comments/comment_data: 저장 전 데이터 보정 (닉네임 기본값)
// 비로그인 방문자에게만 삭제용 비밀번호 칸을 추가한다
add_action('fluent_comments/form_fields', function ($post) {
if (is_user_logged_in()) {
return;
}
echo '<input type="password" name="comment_password" placeholder="비밀번호">';
});
// 비밀번호 없이 등록하면 막는다
add_filter('fluent_comments/validate_submission', function ($valid, $data, $post) {
if (is_wp_error($valid) || is_user_logged_in()) {
return $valid;
}
if (empty($data['comment_password'])) {
return new WP_Error('password_required', '삭제용 비밀번호를 입력해주세요.');
}
return $valid;
}, 10, 3);훅은 플러그인이 “이 이름은 앞으로도 유지하겠다”고 약속한 확장 지점이다. 내부 함수는 그런 약속이 없다. 이 차이가 이번 장애의 전부였다.
워드프레스 치명적인 오류 예방 체크리스트
같은 일을 다시 겪지 않으려고 정리한 목록이다.
- 업데이트 전 백업 : 최소한 wp-content와 DB는 백업해 두자.
- 커스텀 코드는 공식 훅만 : 플러그인 내부 클래스·함수를 직접 부르지 않는다.
- 어쩔 수 없다면 방어 코드 :
class_exists(),is_callable()로 먼저 확인한다. - 자동 업데이트 대상 구분 : 커스텀 코드가 기대는 플러그인은 자동 업데이트를 끄고 직접 확인 후 올린다.
- 점검은 기능까지 : “페이지가 열린다”가 아니라 “댓글이 실제로 등록된다”까지 확인한다.
- 로그 위치는 미리 알아두기 : 장애가 났을 때 찾기 시작하면 늦다.
로그에 아무것도 남지 않는 환경이라면 워드프레스 자체 디버그 로그를 잠깐 켜는 방법도 있다. wp-config.php의 /* 편집을 중지하세요 */ 줄 위에 아래 내용을 넣으면 wp-content/debug.log에 오류가 쌓인다. 자세한 옵션은 워드프레스 공식 디버깅 문서에 정리되어 있다.
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);확인이 끝나면 꼭 다시 지우자. 켜 둔 채로 두면 로그 파일이 계속 커지고, 서버 경로 같은 정보가 파일에 남는다.
맺으며 : 워드프레스 치명적인 오류 앞에서 당황하지 않으려면
cafe24 호스팅을 떠나며에서 썼듯이 호스팅을 떠나 직접 서버를 운영하기 시작하면서, 이런 문제를 고쳐 줄 사람도 이제 나 자신뿐이다. 이번 일을 겪으며 배운 건 결국 두 가지다. 메시지가 아니라 로그를 볼 것, 그리고 고친 뒤에는 기능이 진짜 동작하는지 끝까지 확인할 것.
서버를 직접 구성하고 있다면 Nginx 리버스 프록시와 Let’s Encrypt 무료 SSL 적용 글도 함께 참고해 보자. 다음에 또 업데이트가 사이트를 멈춰 세우더라도, 적어도 어디부터 봐야 할지는 알게 됐다.
첫 댓글을 남겨보세요