خطای 500 وردپرس: از روی صفحه خطا بفهمید کدام بخش خراب شده است

سه پنجره مرورگر کنار هم که با ارقام 5 و 0 و 0 عدد 500 را می‌سازند
محصولات زیر برای شماست...
جدیدترین مقالات
دسترسی سریع
فهرست محتوا

خطای 500 وردپرس همیشه یک صفحه ندارد: گاهی صفحه انگلیسی «Internal Server Error» با امضای وب‌سرور می‌آید، گاهی پیام فارسی «یک خطای مهم در این وب سایت رخ داده است.» و گاهی صفحه‌ای که چیزی در آن نیست. هر کدام از بخش دیگری خراب شده است: فایل تنظیمات وب‌سرور، یک افزونه یا قالب، فایل wp-config.php.

ما علت‌های رایج را یکی‌یکی روی یک وردپرس 7.1.2 فارسی با PHP 8.3 ساختیم. آنچه به وب‌سرور بستگی دارد (.htaccess، php_value، خطای افزونه، حافظه، wp-config.php) را روی سه ترکیب امتحان کردیم: آپاچی با PHP به‌صورت ماژول، آپاچی با PHP-FPM و Nginx با PHP-FPM؛ بقیه را فقط روی آپاچی با ماژول. برای هر علت نوشتیم سایت چه نشان می‌دهد و لاگ چه می‌گوید؛ راه برگشت هم برای هر کدام جز دیتابیس آمده است. LiteSpeed را آزمایش نکردیم.

از روی صفحه خطا می‌شود فهمید کدام بخش خراب شده است

اول صفحه خطا را نگاه کنید و آدرس یک تصویر سایت، مثلاً لوگو، را هم مستقیم در مرورگر باز کنید. در آزمایش ما روی آپاچی، اگر خود تصویر هم 500 می‌داد علت فایل .htaccess بود، و اگر تصویر باز می‌شد (کد 200، یعنی صفحه سالم باز شد) خرابی در PHP یا دیتابیس بود. بعد صفحه‌ای را که خطا می‌دهد با این جدول مقایسه کنید:

آنچه می‌بینیدبخش خرابآنچه در لاگ می‌آیددر همین مقاله
صفحه انگلیسی Internal Server Error آپاچی (در آزمایش ما با نام Apache در پایین آن)؛ تصویر سایت هم 500 می‌دهدفایل .htaccessInvalid command با نام .htaccessفایل htaccess
پیام فارسی «یک خطای مهم در این وب سایت رخ داده است.» (در سایت انگلیسی: «There has been a critical error on this website.»)یک افزونه، یک قالب یا یک mu-plugin، حافظه تمام‌شده، یا یک فایل هسته مثل wp-includes/formatting.php (در آزمایش ما با متن انگلیسی)PHP Fatal error (برای خطای نحوی PHP Parse error) با مسیر فایل خرابافزونه یا قالب؛ فایل هسته: صفحه خالی
صفحه خالی و بدون هیچ متنی؛ Chrome «HTTP ERROR 500» می‌نویسدwp-config.php یا برخی فایل‌های هستهPHP Parse error با نام wp-config.php، یا Failed opening required برای فایل هسته گم‌شدهصفحه خالی
متن «Error establishing a database connection»، یا «خطا در برقراری ارتباط با پایگاه‌داده» روی سایتی که از بسته فارسی وردپرس ساخته شدهدیتابیسچیزی در لاگ PHP نیامدخطای دیتابیس
چهار صفحه‌ای که یک سایت وردپرسی با کد 500 نشان می‌دهد: صفحه انگلیسی Internal Server Error آپاچی، پیام فارسی وردپرس، صفحه خالی Chrome و خطای انگلیسی دیتابیس، هر کدام با نام بخشی که خراب است

این جدول برای وقتی است که PHP خطا را روی صفحه چاپ نکند (تنظیم display_errors خاموش). اگر متن «Fatal error» یا «Parse error» روی خود صفحه آمده، بخش «خود خطا در لاگ نوشته می‌شود» را بخوانید. ردیف اول به لاگ خطای وب‌سرور نیاز دارد و ردیف‌های دوم و سوم به لاگ PHP. فایل debug.log وردپرس فقط وقتی چیزی می‌نویسد که وردپرس بالا آمده باشد، پس خطای .htaccess و wp-config.php را در آن نمی‌بینید.

یک خط اشتباه در فایل htaccess همه درخواست‌ها را 500 می‌کند، حتی تصویرها را

یک خط نامعتبر در ابتدای .htaccess کافی بود. روی آپاچی صفحه اصلی، wp-login.php، پیشخوان و یک تصویر، هر چهار 500 دادند و صفحه خطا را خود آپاچی ساخت، نه وردپرس. لاگ خطای وب‌سرور (بدون تاریخ، شماره فرایند و آدرس کلاینت ابتدای خط) همان خط را نام برد:

CODE
وردپرس نیاز
/var/www/html/.htaccess: Invalid command 'WpnBadDirective', perhaps misspelled or defined by a module not included in the server configuration

نام دستور اشتباه در لاگ هست؛ همان خط را از فایل بردارید.

اگر به لاگ وب‌سرور دسترسی ندارید، در مدیریت فایل (File Manager) هاست .htaccess را به .htaccess-old تغییر نام دهید. در cPanel اگر فایل دیده نمی‌شود، در تنظیمات مدیریت فایل گزینه Show Hidden Files (dotfiles) را بزنید (مستندات cPanel). صفحه اصلی بالا می‌آید، اما صفحه‌های داخلی تا وقتی فایل دوباره ساخته نشود 404 می‌دهند: در آزمایش ما یک نوشته منتشرشده 404 داد و بعد از ذخیره تنظیمات در «تنظیمات > پیوندهای یکتا» دوباره 200 شد، چون وردپرس فایل را از نو نوشت.

برخی راهنماها برای زیاد کردن حافظه PHP این خط را در .htaccess می‌گذارند:

APACHE
وردپرس نیاز
php_value memory_limit 256M

نتیجه به شیوه اجرای PHP بستگی دارد. وقتی PHP ماژول آپاچی بود، حد حافظه از 128M به 256M رسید. وقتی PHP با FPM اجرا می‌شد، آپاچی این دستور را نمی‌شناخت و همه درخواست‌ها، تصویرها هم، 500 شدند. روی Nginx فایل .htaccess خوانده نشد: سایت 200 ماند و حد حافظه هم 128M ماند.

شیوه اجرای PHP را در پیشخوان، «ابزارها > سلامت سایت > اطلاعات > سرور»، در ردیف PHP SAPI می‌بینید (این صفحه فقط وقتی باز می‌شود که سایت بالا باشد؛ وگرنه از پشتیبانی هاست بپرسید): apache2handler یعنی ماژول آپاچی و fpm-fcgi یعنی FPM. اگر مطمئن نیستید، خط را داخل <IfModule mod_php.c> بگذارید:

APACHE
وردپرس نیاز
<IfModule mod_php.c>
php_value memory_limit 256M
</IfModule>

در آزمایش ما این بلوک روی ماژول آپاچی با PHP 8.3 اثر کرد و روی FPM بی‌اثر ماند و خطایی نداد. در PHP 7 نام ماژول mod_php7.c است و این بلوک روی آن اثری ندارد: در آزمایشی جداگانه با PHP 7.4 حد حافظه همان 128M ماند، و با نام mod_php7.c شد 256M. برای FPM راه دیگر WP_MEMORY_LIMIT است که در بخش بعد آمده.

وقتی افزونه یا قالب خراب باشد، وردپرس خودش صفحه خطا نشان می‌دهد

اگر فقط راه برگشت را می‌خواهید: پوشه افزونه خراب را در wp-content/plugins تغییر نام دهید، یا از ایمیل وردپرس وارد «حالت بازیابی» شوید و افزونه را غیرفعال کنید.

چهار خرابی را امتحان کردیم: تابعی که وجود ندارد در یک افزونه، یک خطای نحوی در افزونه، افزونه‌ای که ۴۰۰ مگابایت حافظه می‌خواهد در حالی که حد PHP ۱۲۸ مگابایت است، و همان تابع ناموجود در functions.php یک قالب. هر چهار 500 دادند، با همان پیام فارسی وردپرس، و تصویرها 200 ماندند؛ یک mu-plugin خراب هم همین صفحه را داد. تابع ناموجود و حافظه را روی هر سه ترکیب سرور امتحان کردیم؛ خطای نحوی، قالب، mu-plugin و افزونه‌ای که خطایش داخل هوک است (پایین‌تر توضیح داده‌ایم) را فقط روی آپاچی با ماژول.

این صفحه کار کنترل‌کننده خطای مهلک وردپرس است که از نسخه 5.2 وجود دارد؛ کد 500 را هم خودش می‌فرستد (کد کنترل‌کننده در GitHub). لاگ برای تابع ناموجود و برای حافظه این دو خط را نوشت (ردپای فراخوانی بعد از خط اول حذف شده):

CODE
وردپرس نیاز
PHP Fatal error:  Uncaught Error: Call to undefined function wpn_function_that_does_not_exist() in /var/www/html/wp-content/plugins/wpn-break/wpn-break.php:7
PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 419430432 bytes) in /var/www/html/wp-content/plugins/wpn-break/wpn-break.php on line 9

در هر دو خط، نام پوشه افزونه (wpn-break) در مسیر فایل آمده است.

فعال کردن از صفحه افزونه‌ها همیشه جلوی 500 را نمی‌گیرد. افزونه‌ای که خطایش همان لحظه بارگذاری فایل رخ بدهد فعال نمی‌شود و وردپرس می‌نویسد «به‌دلیل داشتن مشکلی جدی افزونه فعال نشد.» اما افزونه‌ای که تابع ناموجود را داخل یک هوک صدا می‌زد (در آزمایش ما init) فعال شد، و بعد از آن صفحه اصلی، صفحه ورود و پیشخوان 500 دادند.

ایمیل «سایت شما یک مشکل فنی را تجربه می‌کند» فقط گاهی می‌آید

وردپرس برای مدیر ایمیل می‌فرستد، اما نه همیشه. ایمیل نام افزونه، فایل و خط خطا را می‌گوید و پیوند ورود به «حالت بازیابی» را دارد؛ ایمیل آن را «حالت ترمیم» می‌نامد. در آزمایش ما ایمیل فقط پس از اولین درخواست به wp-login.php آمد؛ صفحه اصلی، آدرس REST و wp-cron.php پیش از آن ایمیلی نفرستادند، و درخواست دوم به wp-login.php هم نفرستاد (حد پیش‌فرض در کد وردپرس یک روز است). برای خطا در یک mu-plugin، که فایلش در پوشه افزونه یا قالب نیست، ایمیلی نیامد. پس اگر ایمیلی نیامده، یک بار خودتان صفحه ورود را باز کنید.

حالت بازیابی افزونه خراب را بدون مدیریت فایل غیرفعال می‌کند

پیوندی که در ایمیل هست شما را وارد «حالت بازیابی» می‌کند و طبق متن ایمیل یک روز اعتبار دارد. بعد از ورود، افزونه خراب در صفحه افزونه‌ها با خطایش دیده می‌شود و می‌توانید غیرفعالش کنید:

صفحه افزونه‌ها در حالت بازیابی: پیام «شما در حالت بازیابی هستید»، فیلتر «متوقف شده» و ردیف افزونه خراب با پیوند غیرفعال کردن و پیام «این افزونه به درستی بارگذاری نشد و در حین حالت ترمیم متوقف شد.»

بازدیدکننده تا آن لحظه هنوز 500 می‌بیند. صفحه اصلی با کوکی حالت بازیابی 200 داد و بدون آن 500. بعد از زدن «غیرفعال کردن» صفحه اصلی بدون کوکی هم 200 داد.

برای خرابی قالب هم همین راه کار می‌کند: صفحه قالب‌ها در حالت بازیابی قالب خراب را با پیام «خطا: این پوسته در بارگذاری صحیح ناموفق بود و در داخل بخش مدیریت متوقف شد.» نشان می‌دهد، و بعد از فعال کردن قالب دیگری (ما Twenty Twenty-Five را فعال کردیم) صفحه اصلی 200 داد.

بدون ایمیل، پوشه همان افزونه را تغییر نام دهید

اگر ایمیل نیامد یا به آن دسترسی ندارید، در مدیریت فایل فقط پوشه همان افزونه را در wp-content/plugins تغییر نام دهید؛ نام پوشه در مسیر لاگ آمده است (راه دیدن لاگ در بخش «خود خطا در لاگ نوشته می‌شود» است). صفحه اصلی و wp-login.php چند ثانیه بعد 200 شدند (در محیط آزمایشی ما، یک ایمیج Docker، تغییر فایل تا دو ثانیه دیده نمی‌شد). اگر لاگ به wp-content/mu-plugins اشاره می‌کند، ایمیل و حالت بازیابی کمکی نمی‌کنند و باید همان فایل را تغییر نام دهید؛ در آزمایش ما صفحه اصلی بعد از این کار 200 داد. اگر به مدیریت فایل هاست دسترسی ندارید، درخواست رفع خطای سایت را ثبت کنید.

تغییر نام کل پوشه plugins خطرناک‌تر است. در آزمایش ما با پوشه تغییرنام‌داده سایت 200 داد، اما همین که صفحه افزونه‌ها در پیشخوان باز شد، وردپرس همه افزونه‌های فعال را که فایلشان پیدا نمی‌شد (افزونه آزمایشی ما و Akismet) از فهرست فعال‌ها برداشت؛ صفحه اصلی، صفحه ورود و خانه پیشخوان به‌تنهایی این کار را نکردند. با برگرداندن نام پوشه هیچ‌یک از آن دو افزونه دوباره فعال نشد (کد plugins.php در GitHub).

افزایش WP_MEMORY_LIMIT خطای حافظه را برطرف کرد

اگر لاگ از حافظه تمام‌شده می‌گوید، حد حافظه وردپرس را بالا ببرید. این خط را بالای خطی بگذارید که می‌گوید «That’s all, stop editing!»:

PHP
وردپرس نیاز
define( 'WP_MEMORY_LIMIT', '512M' );

افزونه آزمایشی ما ۴۰۰ مگابایت می‌خواست (عدد را خودمان ساختیم و مصرف یک افزونه واقعی نیست) و با این خط روی هر سه ترکیب سرور بالا آمد. اینکه هاست اجازه تغییر این حد را بدهد آزمایش نشد.

صفحه خالی معمولاً یعنی وردپرس هنوز بالا نیامده است

یک خطای نحوی در wp-config.php روی هر سه ترکیب سرور، و نبودن wp-settings.php روی آپاچی با ماژول، هر دو 500 با بدنه خالی دادند. wp-config.php پیش از ثبت کنترل‌کننده خطای وردپرس اجرا می‌شود (کد وردپرس)، پس نه صفحه خطای وردپرس هست و نه ایمیل؛ در آزمایش ما هم ایمیلی نیامد. علت فقط در لاگ PHP است:

CODE
وردپرس نیاز
PHP Parse error:  syntax error, unexpected token ";" in /var/www/html/wp-config.php on line 2

عدد آخر شماره خطی از فایل است که باید باز کنید. راه برگشت این است که همان خط را درست کنید یا نسخه سالم فایل را از بکاپ برگردانید: در آزمایش ما با برگرداندن wp-config.php سایت 200 داد، و نبودن wp-settings.php هم با برگرداندن همان فایل برطرف شد. همه فایل‌های هسته صفحه خالی نمی‌سازند: نبودن wp-includes/formatting.php صفحه خطای وردپرس، این بار به انگلیسی، داد، و نبودن wp-includes/load.php یا wp-includes/plugin.php مثل wp-settings.php صفحه خالی. اگر WP_DISABLE_FATAL_ERROR_HANDLER در wp-config.php true باشد، خطای افزونه هم صفحه خالی می‌دهد. اگر نسخه سالم فایل را ندارید، درخواست رفع خطای سایت را ثبت کنید.

خود خطا در لاگ نوشته می‌شود

جای لاگ PHP را هاست تعیین می‌کند؛ اگر آن را پیدا نکردید از پشتیبانی هاست بپرسید. راه دوم لاگ خود وردپرس است. فایل wp-config.php از قبل خطی دارد که WP_DEBUG را تعریف می‌کند (در فایل نمونه وردپرس 7.1.2 مقدار آن false است)؛ همان خط را روی true بگذارید و دو خط دیگر را زیر آن، بالای خطی که می‌گوید «That’s all, stop editing!»، اضافه کنید:

PHP
وردپرس نیاز
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

با همین ترتیب خطا در wp-content/debug.log نوشته شد و بازدیدکننده همچنان صفحه خطای وردپرس با کد 500 را دید. در ایمیج رسمی Docker وردپرس که ما استفاده کردیم، خط WP_DEBUG از یک متغیر محیطی خوانده می‌شود؛ ما همان خط را عوض کردیم.

اگر سه خط را زیر خط قدیمی WP_DEBUG بگذارید، همان خط قدیمی برنده می‌شود: در آزمایش ما debug.log خالی ماند و لاگ PHP نوشت «Constant WP_DEBUG already defined». سه خط در انتهای فایل، بعد از require مربوط به wp-settings.php، هم کمکی نکرد: خطا درون همان require رخ می‌دهد و debug.log خالی ماند.

اگر WP_DEBUG روی false باشد، WP_DEBUG_LOG چیزی نمی‌نویسد: debug.log خالی ماند، و مستندات وردپرس هم می‌گوید برای کار کردن WP_DEBUG_LOG باید WP_DEBUG فعال باشد.

اگر WP_DEBUG روشن باشد و WP_DEBUG_DISPLAY را ننویسید (پیش‌فرضش true است)، خود خطا روی صفحه چاپ می‌شود. PHP در این حالت خودش کد 500 نمی‌گذارد؛ فقط وقتی display_errors خاموش باشد می‌گذارد (کد PHP در GitHub). کد نهایی به بافر خروجی بستگی دارد: در ایمیج Docker ما که output_buffering=0 داشت، کد 200 ماند و صفحه خطای وردپرس نیامد؛ با output_buffering=4096، مقداری که php.ini-production و php.ini-development می‌آورند، وردپرس خودش 500 فرستاد و متن خطا و صفحه خطای وردپرس هر دو آمدند. روشن بودن display_errors در تنظیمات PHP هم همین دو نتیجه را داد. مسیر چاپ‌شده روی صفحه نام پوشه افزونه یا قالب خراب را می‌گوید.

روی سایت زنده متن خطای چاپ‌شده مسیر فایل‌های سرور را به همه نشان می‌دهد، و مستندات وردپرس این ابزارها را برای سایت زنده توصیه نمی‌کند. بعد از پیدا کردن علت، WP_DEBUG را خاموش کنید و فایل wp-content/debug.log را پاک کنید: در آزمایش ما این فایل با آدرس مستقیم هم خوانده می‌شد، حتی بعد از خاموش کردن WP_DEBUG.

خطای دیتابیس و خطای 503 راه خودشان را دارند

وقتی رمز دیتابیس را در wp-config.php اشتباه گذاشتیم و وقتی دیتابیس را خاموش کردیم، سایت 500 داد و متن انگلیسی «Error establishing a database connection» را نشان داد؛ تصویرها 200 ماندند. رفع آن در مقاله خطای اتصال به دیتابیس آمده است. خطای 503 هم چیز دیگری است و در مقاله Service Unavailable توضیح داده شده.

پرسش‌های متداول

خطای 500 همیشه از افزونه است؟

نه. در آزمایش ما یک خط اشتباه در htaccess، خطا در یک افزونه یا قالب، حافظه تمام‌شده، خطا در wp-config.php و قطع دیتابیس هر کدام 500 دادند. صفحه خطا نشان می‌دهد کدام بخش است و لاگ، جز برای دیتابیس، نام فایل خراب را می‌گوید.

چرا بعد از اضافه کردن php_value به htaccess سایت 500 داد؟

اگر PHP با FPM اجرا شود، آپاچی دستور php_value را نمی‌شناسد و همه درخواست‌ها را 500 می‌کند؛ در آزمایش ما همین شد. روی ماژول آپاچی همین خط کار کرد و روی Nginx خوانده نشد. خط را بردارید یا داخل IfModule mod_php.c بگذارید (در PHP 7 نام ماژول mod_php7.c است).

ایمیل «سایت شما یک مشکل فنی را تجربه می‌کند» نیامد، چه کنم؟

در آزمایش ما ایمیل فقط برای اولین درخواست به wp-login.php آمد، نه برای صفحه اصلی، و برای خطای یک mu-plugin یا wp-config.php نیامد. صفحه ورود را یک بار باز کنید و اگر ایمیلی نیامد، پوشه همان افزونه را در wp-content/plugins تغییر نام دهید (برای mu-plugin، همان فایل را در wp-content/mu-plugins)؛ نام پوشه در مسیر لاگ آمده است.

اگر پوشه plugins را تغییر نام دهم و برگردانم، افزونه‌ها فعال می‌مانند؟

اگر صفحه افزونه‌ها در این فاصله باز شده باشد، نه. در آزمایش ما وردپرس افزونه‌هایی را که فایلشان پیدا نمی‌شد از فهرست فعال‌ها برداشت و با برگرداندن پوشه فعال نشدند. صفحه اصلی، صفحه ورود و خانه پیشخوان به‌تنهایی این کار را نکردند.

چرا به‌جای کد 500، متن خطا روی صفحه چاپ شده و کد 200 است؟

وقتی WP_DEBUG روشن است و WP_DEBUG_DISPLAY پیش‌فرض است، یا display_errors روشن است، خطا روی صفحه چاپ می‌شود و PHP خودش کد 500 نمی‌گذارد. کد نهایی به output_buffering بستگی دارد: در آزمایش ما با output_buffering=0 کد 200 ماند و صفحه خطای وردپرس نیامد، و با output_buffering=4096 خود وردپرس 500 فرستاد و صفحه خطای وردپرس هم آمد. لاگ را با WP_DEBUG_LOG بخوانید (با WP_DEBUG روشن) و WP_DEBUG_DISPLAY را false بگذارید.

تصویر سمانه جعفری
سمانه جعفری
پیشنهاد میکنیم این مقالات را هم بخوانید

دیدگاه یا پرسش خود را بنویسید