2026年7月12日

2026年7月12日

WordPressのプラグインが勝手に無効化される原因と調べ方・再発防止

プラグインが「いつの間にか無効になっている」とき、WordPress本体がプラグインを止める仕組みは限られています。多くはファイルが見つからない、有効化の途中で致命的エラーが出た、データベースの active_plugins が書き換わった、プラグイン自身が動作条件を満たさず自分を止めた、のいずれかです。この記事では、どの原因かを切り分ける手順と、次に起きたときに「誰が・いつ・どの処理で」止めたかを記録する方法を説明します。

まず確認したいこと:本当に「無効化」されているか

最初に、状態を正確に把握します。似た症状でも原因がまったく違うためです。

  • プラグイン一覧で「無効」になっている:active_plugins オプションからそのプラグインが外れています。この記事の主な対象です。
  • リカバリーモードで「一時停止」と表示される:WordPress 5.2 以降の致命的エラー保護機能によるもので、無効化とは別物です。管理者がリカバリーモードのリンクからログインしている間だけ、原因のプラグインが読み込まれない状態になります。一般の訪問者には「重大なエラー」の画面が出続けるので、プラグインの修正か無効化の判断が必要です。
  • 有効なのに機能しない:無効化ではなく、キャッシュ・競合・設定の問題です。

一覧画面の上部に「プラグインファイルが存在しないため停止した」という趣旨の通知が出ている場合は、次の章の「ファイルが見つからない」が原因です。WP-CLI が使えるなら、現在有効なプラグインをそのまま確認できます。

wp plugin list --status=active
wp option get active_plugins --format=json

WordPressがプラグインを止める主なパターン

ファイルが見つからない

管理画面のプラグイン一覧を開くと、WordPress は validate_active_plugins() で有効なプラグインのファイルが実在するかを調べ、見つからないものを無効化します。次のような場面で起こります。

  • プラグインの自動更新・手動更新が途中で失敗し、フォルダが消えたり中身が欠けたりした
  • FTP やファイルマネージャーでフォルダ名を変えた(トラブル対応で plugins フォルダごとリネームする手順を誰かが実行した場合も含む)
  • サーバー移行やバックアップ復元で、wp-content/plugins の一部が戻っていない
  • セキュリティ製品やホスティング会社のスキャンが、マルウェア判定したファイルを隔離した

この経路の無効化は「サイレント」に行われ、後述する deactivated_plugin フックが実行されません。ログを仕込むときに注意が必要な点です。

有効化の時点で致命的エラーが出た

プラグインを有効にした瞬間に PHP の致命的エラー(Fatal error)が出ると、WordPress は有効化を取り消します。「勝手に無効になった」ように見えても、実際には一度も有効になっていなかったというケースです。PHP のバージョンが要件を満たさない、依存するライブラリや拡張モジュールがない、別プラグインと関数名・クラス名が衝突している、などが典型です。プラグインのヘッダーに書かれた必要 PHP バージョンを満たさない場合は、そもそも有効化できません。

プラグイン自身が自分を止めた

多くのプラグインは、PHP バージョンや前提プラグイン(WooCommerce の拡張機能なら WooCommerce 本体)を起動時にチェックし、条件を満たさないと deactivate_plugins() で自分自身を停止します。サーバー側で PHP のバージョンが変わった、前提プラグインを先に止めた、といった変化の直後に起きやすいパターンです。

データベースの値が変わった

有効なプラグインの一覧は wp_options テーブルの active_plugins(マルチサイトのネットワーク有効化は wp_sitemeta の active_sitewide_plugins)に保存されています。古いデータベースバックアップを戻した、ステージング環境から DB だけを上書きした、SQL で直接値を編集してシリアライズ形式が壊れた、といった操作で一覧が変わります。Redis などの永続オブジェクトキャッシュを使っている場合、DB を直接直したのに画面が変わらないこともあるため、修正後は wp cache flush でキャッシュを消してから確認します。

ホスティング側・運用ツールによる停止

一部のマネージドホスティングは、利用を認めていないプラグインを自動で停止します。また、複数サイトを一括管理するツールや、運用担当者の WP-CLI スクリプトが止めていることもあります。人の操作は記録がないと特定が難しいため、次の章のログが役立ちます。

原因を切り分ける手順

1. エラーログを有効にする

致命的エラーが絡むかを知るため、wp-config.php でデバッグログを有効にします。編集前に wp-config.php のバックアップを取ってください。

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

wp-content/debug.log にエラーが記録されます。調査が終わったら設定を戻し、ログファイルを削除します。ログにはサーバー上のファイルパスなどの情報が含まれ、URL から直接読めてしまうと危険だからです。あわせてサーバーの PHP エラーログ(ホスティングの管理画面で見られることが多い)も確認します。

2. ファイルの状態を確かめる

wp-content/plugins/ に該当フォルダがあり、メインのPHPファイルが揃っているかを見ます。WordPress.org で配布されているプラグインなら、改ざんや欠けを公式のチェックサムと照合できます。

wp plugin verify-checksums プラグインのスラッグ

不一致が出たら、同じバージョンを入れ直すのが早道です。ファイルの所有者やパーミッションが変わって PHP から読めない場合も同様の症状になるため、更新を実行したユーザーとWebサーバーの実行ユーザーが一致しているかも確認します。

3. 再度有効化して反応を見る

ステージング環境があればそちらで、なければアクセスの少ない時間帯に有効化を試します。エラーで有効化できなければ「致命的エラー」の系統、有効化できるのにしばらくして止まるなら「プラグイン自身」「DB の書き換え」「外部の操作」の系統と絞り込めます。

誰が止めたかを記録する mu-plugin

再発するのに原因が分からないときは、無効化の瞬間を記録します。wp-content/mu-plugins/ に次のファイルを置きます(フォルダがなければ作成)。mu-plugins は管理画面から無効化できず、通常のプラグインより先に読み込まれるため、記録係に向いています。

<?php
/**
 * Plugin Name: Plugin Deactivation Logger
 * Description: プラグインの無効化と active_plugins の変化を error_log に記録する。
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

function pdl_context() {
	if ( defined( 'WP_CLI' ) && WP_CLI ) {
		return 'wp-cli';
	}
	if ( wp_doing_cron() ) {
		return 'cron';
	}
	if ( wp_doing_ajax() ) {
		return 'ajax';
	}
	return 'web';
}

// 通常の無効化(管理画面・WP-CLI・プラグイン自身の deactivate_plugins())
add_action( 'deactivated_plugin', function ( $plugin, $network_wide ) {
	$user  = wp_get_current_user();
	$trace = wp_debug_backtrace_summary( null, 0, false );
	error_log( sprintf(
		'[plugin-deactivated] %s network=%s user=%s ctx=%s trace=%s',
		$plugin,
		$network_wide ? 'yes' : 'no',
		$user->exists() ? $user->user_login : '-',
		pdl_context(),
		implode( ' <- ', array_slice( $trace, 0, 10 ) )
	) );
}, 10, 2 );

// サイレントな無効化も含め、active_plugins から外れたものを記録
add_action( 'update_option_active_plugins', function ( $old_value, $value ) {
	$removed = array_diff( (array) $old_value, (array) $value );
	if ( $removed ) {
		error_log( '[active_plugins] removed: ' . implode( ', ', $removed ) . ' ctx=' . pdl_context() );
	}
}, 10, 2 );

deactivated_plugin は通常の無効化で実行され、バックトレースから「どのファイルの処理が止めたか」が分かります。ファイルが見つからない場合の無効化はこのフックを通らないため、update_option_active_plugins で値の変化も拾っています。逆に、SQL で直接テーブルを書き換えた場合はどちらのフックも動かないので、記録が何も残らなければ DB の直接操作やバックアップ復元を疑います。マルチサイトのネットワーク有効化を追う場合は update_site_option_active_sitewide_plugins にも同様の処理を足します。

再発を防ぐための運用

  • 更新はステージングで先に試す:特に PHP バージョンの変更やメジャーアップデートの前は、本番と同じ構成で有効化まで確認します。
  • 自動更新の範囲を決める:重要なプラグインは自動更新を止め、更新後の動作確認ができる時間帯に手動で行う運用も選択肢です。
  • ファイルと DB をセットでバックアップする:片方だけ戻すと active_plugins とファイルの実態がずれます。
  • 止まると困る処理は mu-plugin に移す:サイトの根幹に関わる短い処理は、無効化されない mu-plugins に置くと影響を抑えられます。
  • ホスティングの方針を確認する:禁止プラグインや自動スキャンの仕様は各社で異なります(2026年10月現在も、各社のヘルプページで公開されていることが多いです)。

まとめ

  • 「無効」と「リカバリーモードの一時停止」は別物。まず状態を正確に確認する
  • WordPress がプラグインを止めるのは、ファイルがない・有効化時の致命的エラー・プラグイン自身の停止・DB の書き換え・外部ツールの操作がほとんど
  • debug.log とファイルの照合で、エラー系かファイル系かを切り分ける
  • 再発するなら deactivated_plugin と update_option_active_plugins を mu-plugin で記録し、誰がどの経路で止めたかを特定する
  • 更新はステージングで試し、ファイルと DB はセットでバックアップする

お気軽にご相談ください

お見積りへ お問い合わせへ
▲