خطای ⁦500 Internal Server Error⁩ چیست و چگونه رفع می‌شود؟

تاریخ انتشار:

14 دقیقه مطالعه

Acar Diveroli
نویسنده: Acar Diveroli
یک واحد سرور ایزومتریک با دریچه‌های تهویه و پیچ، پلاک وضعیت ⁦HTTP 500⁩ و یک چراغ قرمز خطا؛ پلاکی آبی بالای آن شناور است

دکمه پرداخت یک سفارش را می‌زنید و به جای صفحه بعدی، صفحه‌ای تقریباً خالی می‌بینید: ⁦"500 Internal Server Error"⁩ با حروف درشت و زیر آن واژه nginx. در سایتی دیگر گوگل کروم صفحه خودش را نشان می‌دهد، «این صفحه کار نمی‌کند»، و در پایین آن ⁦"HTTP ERROR 500"⁩. درون یک برنامه واژه‌ها فرق می‌کنند، مثلاً ⁦"The call failed on the server; see server log for details"⁩، اما عدد همان است.

در ادامه می‌خوانید این کد یعنی چه و چرا این‌قدر کم می‌گوید، صفحه‌ای را که می‌بینید چه کسی ساخته است، 500 چه فرقی با 502، 503 و 504 دارد، و بازدیدکننده‌ها، صاحبان سایت و اسکریپت‌ها در برابر آن چه باید بکنند.

خطای ⁦500 Internal Server Error⁩ یعنی چه؟

استاندارد HTTP این کد را در یک جمله تعریف می‌کند: سرور «با وضعیتی غیرمنتظره روبه‌رو شده که مانع انجام درخواست شده است» (⁦RFC 9110⁩، بخش 15.6.1). هر کدی که با 5 شروع می‌شود خطای سرور است، یعنی سرور می‌داند ایراد از خودش است؛ 500 کدی است که وقتی هیچ کد دقیق‌تری مناسب نباشد به کار می‌رود.

به همین دلیل پیام این‌قدر کم می‌گوید. وب‌سرور، یعنی برنامه‌ای که اتصال‌ها را می‌پذیرد، مانند nginx یا Apache، درخواست شما را به برنامه‌ای سپرده که صفحه‌ها را می‌سازد، و جایی در میانه این کار برنامه شکست خورده است. وب‌سرور فقط می‌داند هیچ صفحه قابل‌استفاده‌ای برنگشته، پس با 500 پاسخ می‌دهد؛ جزئیات به لاگ خطایی رفته که فقط گرداننده سایت می‌تواند بخواند.

صفحه‌ای را که می‌بینید چه کسی فرستاده است؟

ظاهر صفحه خطا نشان می‌دهد کدام برنامه کار را رها کرده و چه مقدار از سایت هنوز کار می‌کند.

آنچه می‌بینیدفرستندهمعنای آن
طراحی خود سایت، یک عذرخواهی، گاهی یک شناسه درخواستبرنامهبرنامه اجرا می‌شود و خطای خودش را گرفته است؛ شناسه به سطر لاگ اشاره می‌کند
صفحه‌ای سفید، ⁦"500 Internal Server Error"⁩ و زیر آن nginx یا Apacheوب‌سروربرنامه از کار افتاده یا چیز قابل‌استفاده‌ای نفرستاده است
«این صفحه کار نمی‌کند»، «example.com درحال حاضر نمی‌تواند این درخواست را انجام دهد.»، ⁦"HTTP ERROR 500"⁩گوگل کروم500 با بدنه خالی آمده است؛ مرورگر صفحه خودش را کشیده است

سطر آخر را با یک سرور آزمایشی کوچک روی رایانه خودمان بررسی کردیم که به هر درخواست با وضعیت 500 و بدون هیچ صفحه‌ای پاسخ می‌دهد؛ در ⁦Chromium 145⁩ دقیقاً همین سه سطر دیده شد، با نام میزبان ما در سطر میانی، و یک دکمه بارگذاری دوباره. متن فارسی عنوان، سطر میزبان و دکمه مجدد بار کردن از فایل ترجمه فارسی Chromium گرفته شده است (components_strings_fa.xtb)؛ ⁦"HTTP ERROR 500"⁩ را کد اضافه می‌کند و هرگز ترجمه نمی‌شود.

خطای 500 گام‌به‌گام چگونه رخ می‌دهد؟

  1. مرورگر شما درخواست را می‌فرستد، همراه با آدرس، کوکی‌های شما و داده‌های فرم، اگر باشد.
  2. وب‌سرور آن را به برنامه می‌سپارد، برنامه‌ای که صفحه‌ها را در لحظه می‌سازد؛ فایل‌های ایستا را خودش تحویل می‌دهد.
  3. برنامه در میانه راه شکست می‌خورد: خطایی مدیریت‌نشده، پایگاه داده‌ای که پاسخ نمی‌دهد، یک سطر پیکربندی خراب، اسکریپتی که از محدودیت حافظه‌اش گذشته است.
  4. چیزی با 500 پاسخ می‌دهد: اگر برنامه خطا را گرفته باشد صفحه خودش، اگر از کار افتاده باشد صفحه کلی وب‌سرور یا پاسخی خالی.
  5. مرورگر شما آنچه را گرفته نشان می‌دهد، یا اگر بدنه خالی بوده، صفحه «این صفحه کار نمی‌کند» خودش را.

تفاوت 500، 502، 503 و 504 چیست؟

هر چهار کد خطای سرور هستند، اما هرکدام بخش متفاوتی را که شکست خورده نام می‌برند. 500 می‌گوید خود برنامه شکست خورده است؛ 502، 503 و 504 درباره دروازه (gateway) حرف می‌زنند، یعنی سروری که جلوی برنامه ایستاده (یک ریورس پروکسی، یک متعادل‌کننده بار یا یک CDN) و درخواست بازدیدکنندگان را به آن می‌رساند.

کدکدام بخش شکست خوردعلت معمولبازدیدکننده چه کند
500برنامهخطای کد، پیکربندی خراب، کمبود حافظه، پایگاه داده از کار افتادهیک بار دوباره بارگذاری کنید، سپس گزارش دهید
502دروازه پاسخی نامعتبر گرفته یا اصلاً پاسخی نگرفتهبرنامه متوقف شده یا از کار افتادهیک دقیقه صبر کنید و دوباره بارگذاری کنید
503سرور فعلاً نمی‌تواند خدمت بدهدبار بیش از حد، نگه‌داریصبر کنید، صفحه وضعیت را ببینید
504دروازه بیش از حد منتظر ماندهبرنامه کند، درخواست طولانیبعداً صفحه سبک‌تری را امتحان کنید

یک خرابی واحد می‌تواند با هر یک از این دو کد دیده شود: اگر برنامه پیش از پاسخ دادن از کار بیفتد و nginx جلوی آن باشد، nginx 502 گزارش می‌کند؛ اگر برنامه خطا را بگیرد و خودش پاسخ بدهد، 500 می‌بینید. سمت دروازه را در خطای ⁦502 Bad Gateway⁩ چیست و چگونه رفع می‌شود؟ توضیح داده‌ایم.

آیا خطای 500 تقصیر شماست؟

تقریباً هرگز، و هرگز به خاطر اتصال شما: درخواست رسیده است. با این حال درخواست شما می‌تواند آغازگر خطا باشد، مثلاً مقداری در فرم که کد انتظارش را نداشته، یا یک آپلود خیلی بزرگ؛ باگ مال سایت است، اما تا وقتی سایت آن را رفع نکند فقط برای شما رخ می‌دهد. یک کوکی یا نشست ورود کهنه هم می‌تواند برنامه را گیج کند؛ به همین دلیل پاک کردن کوکی‌های سایت گاهی خطای 500 را برطرف می‌کند که با بارگذاری دوباره نمی‌رود.

پروکسی یا VPN هم باعث 500 نمی‌شود: خطا پس از رسیدن درخواست به سایت ساخته می‌شود، پس آدرس آی‌پی دیگری آن را از میان نمی‌برد.

به‌عنوان بازدیدکننده چه کاری از دستتان برمی‌آید؟

  1. یک بار دوباره بارگذاری کنید، سپس چند دقیقه صبر کنید. کلید ⁦F5⁩ یا دکمه مجدد بار کردن را در صفحه خطای کروم بزنید؛ پس از آن فقط بر سروری که همین حالا هم در تنگناست بار می‌افزایید.
  2. صفحه دیگری از همان سایت را امتحان کنید. اگر صفحه اصلی باز می‌شود اما پرداخت شکست می‌خورد، سایت روشن است و فقط یک قابلیت آن خراب است.
  3. سایت را در گوشی با اینترنت همراه امتحان کنید. اگر آنجا هم شکست خورد، خرابی برای همه است و هیچ کاری روی رایانه شما آن را تغییر نمی‌دهد. عوض کردن خروجی با پروکسی یا VPN همین آزمایش است؛ با پروکسی مسکونی می‌توانید آن را در یک دقیقه از کشوری دیگر تکرار کنید.
  4. صفحه وضعیت سایت را ببینید. سرویس‌های بزرگ قطعی‌ها را آنجا اعلام می‌کنند؛ برنامه‌ای که پیوسته 500 نشان می‌دهد، از طریق API خود به همان قطعی برخورده است.
  5. کوکی‌های سایت را پاک کنید، اما فقط وقتی خطا پس از صبر کردن هم می‌ماند و در صفحه‌های مختلف دنبالتان می‌آید. در کروم روی رایانه: بیشتر > حذف داده‌های مرور، یک محدوده زمانی انتخاب کنید، کوکی‌ها و دیگر داده‌های سایت را علامت بزنید و سپس حذف داده‌ها را بزنید (گام‌های گوگل). این کار شما را از سایت‌ها خارج می‌کند، پس آن را برای آخر بگذارید.
  6. گزارش دهید، با آدرس دقیق، زمان، آنچه کلیک کردید و هر شناسه درخواستی که روی صفحه چاپ شده است.

راه‌اندازی دوباره مودم، عوض کردن سرور DNS یا نصب دوباره مرورگر اینجا کاری نمی‌کنند: این‌ها روی بخشی از مسیر اثر می‌گذارند که از قبل کار کرده است.

اگر سایت متعلق به شماست: علت را چگونه پیدا کنید؟

500 برای بازدیدکننده عمداً مبهم است، اما در لاگ هرگز مبهم نیست. این موارد را به ترتیب بررسی کنید؛ بیشتر خطاهای 500 در سه مورد نخست تمام می‌شوند.

  1. نخست لاگ خطا را بخوانید. Apache لاگ خطای (error log) خود را نخستین جایی می‌نامد که هنگام بروز مشکل باید نگاه کرد؛ دستور ErrorLog محل آن را تعیین می‌کند، که در Unix معمولاً فایلی به نام error_log است (مستندات لاگ Apache). nginx به‌طور پیش‌فرض در logs/error.log می‌نویسد و PHP در فایل error_log خودش یا در لاگ وب‌سرور. دقیقه‌ای را که 500 رخ داده پیدا کنید: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted مشکل حافظه است، Premature end of script headers در Apache اسکریپتی است که پیش از فرستادن صفحه از کار افتاده، و یک ردیابی پشته (stack trace) نام فایل و شماره سطر را می‌گوید.
  2. آخرین تغییر را برگردانید. خطای 500 که درست پس از یک به‌روزرسانی، یک استقرار یا ویرایش پیکربندی شروع می‌شود، تا خلافش ثابت نشده کار همان تغییر است؛ نخست آن را به حالت قبل برگردانید.
  3. افزونه‌ها و پوسته‌ها. راهنمای وردپرس برای Internal Server Error می‌گوید همه افزونه‌ها را غیرفعال کنید و به یک پوسته پیش‌فرض بروید (خطاهای رایج وردپرس)؛ اگر سایت برگشت، افزونه‌ها را یکی‌یکی دوباره فعال کنید.
  4. فایل .htaccess. در Apache این فایل پیکربندی که در هر پوشه قرار می‌گیرد در هر درخواست خوانده می‌شود، پس یک سطر خراب همه صفحه‌ها را خراب می‌کند. راهنمای وردپرس فایل .htaccess خراب را محتمل‌ترین علت می‌داند: نام آن را به .htaccess_old تغییر دهید و اگر سایت باز شد، آن را از Settings > Permalinks (تنظیمات > پیوندهای یکتا) دوباره بسازید. دستوری که AllowOverride اجازه‌اش را نمی‌دهد، یا یک خطای نگارشی، خطای سروری تولید می‌کند که علتش در لاگ ثبت می‌شود.
  5. محدودیت‌های PHP. PHP اسکریپتی را که بیش از memory_limit (به‌طور پیش‌فرض 128M) حافظه بگیرد متوقف می‌کند و اسکریپتی را که بیش از max_execution_time (روی وب‌سرور به‌طور پیش‌فرض 30 ثانیه) طول بکشد پایان می‌دهد. محدودیت را در php.ini یا تنظیمات PHP شرکت میزبانی بالا ببرید، اما نیاز به حافظه‌ای را که پیوسته بیشتر می‌شود یک باگ بدانید.
  6. مجوزها و وابستگی‌ها. وب‌سرور با کاربر خودش اجرا می‌شود: اسکریپتی که نمی‌تواند بخواند یا پوشه‌ای که نمی‌تواند در آن بنویسد، به جای پیامی روشن به 500 می‌رسد. پایگاه داده‌ای که از کار افتاده، کلید API یا گواهی منقضی‌شده، یا دیسک پر هم همین‌طور؛ این‌ها در لاگ خود برنامه هستند.
  7. پنل هاستینگ شما. در هاستینگ اشتراکی پنل لاگ را نشان می‌دهد: در cPanel بخش Errors (خطاها) زیر Metrics (معیارها) تا 300 مورد از تازه‌ترین سطرها را فهرست می‌کند. اگر سطرها به خود سرور اشاره دارند، یا همه سایت‌های روی سرور خطا می‌دهند، با زمان، URL و سطرهای لاگ برای شرکت میزبانی تیکت بزنید.

خزنده‌های گوگل با دیدن خطاهای ⁦5xx⁩ سرعت خزش را کم می‌کنند و سرانجام آدرس‌هایی را که پیوسته خطا می‌دهند کنار می‌گذارند؛ پس خطای 500 که مدتی بماند به رتبه سایت آسیب می‌زند. ابزار پایشی که هر دقیقه چند صفحه مهم را می‌گیرد، پیش از همه به شما هشدار می‌دهد؛ بررسی‌هایی را که از چند آدرس ثابت و اختصاصی پروکسی دیتاسنتر می‌آیند می‌توان روی سرور در فهرست مجاز گذاشت و از آمار خطاها بیرون نگه داشت.

اسکریپت یا اسکرپر با 500 چگونه باید رفتار کند؟

500 را موقت اما نه رایگان بدانید: چند بار با فاصله‌هایی که هر بار بلندتر می‌شوند دوباره تلاش کنید، سپس از آن آدرس دست بکشید.

  • تعداد تلاش‌ها را محدود کنید و فاصله را بلندتر کنید. یک ثانیه، سپس دو، سپس چهار، و پس از سه چهار تلاش متوقف شوید؛ حلقه‌ای که یک آدرس را پیاپی می‌کوبد قطعی را بدتر می‌کند.
  • 500 زیر بار یعنی سرعت را کم کنید. اگر سایت در حالی که خزنده شما با هم‌زمانی بالا اجرا می‌شود شروع به برگرداندن 500 کرد، تعداد درخواست‌های موازی را کم کنید. هرگز برای عبور آدرس آی‌پی را عوض نکنید: برنامه برای همه شکست می‌خورد.
  • بدنه پاسخ را در لاگ ثبت کنید. یک خطای JSON، یک شناسه درخواست یا یک ردیابی پشته می‌گوید خرابی از شماست (یک پارامتر نادرست) یا از آن‌ها، و 500 واقعی را از مسدودسازی جدا می‌کند: 403 یا 429 همراه با صفحه چالش تصمیمی درباره ترافیک شماست، نه خطای سرور. ⁦429 Too Many Requests⁩ چیست؟ خطای Rate Limit و رفع آن آن‌ها را توضیح می‌دهد.

مثال زیر این قواعد را با کتابخانه Requests پایتون پیاده می‌کند. آن را روی سرور آزمایشی محلی خودمان اجرا کردیم که صفحه /flaky آن دو بار 500 و سپس 200 برمی‌گرداند و صفحه /text آن همیشه 500 (⁦Python 3.13⁩، ⁦Requests 2.34⁩):

python
import time

import requests

URL = "http://127.0.0.1:18500/flaky"  # our local test server; put the page you need here
PROXIES = None  # or {"http": "http://user:pass@pr.proxynet.io:8000", "https": "http://user:pass@pr.proxynet.io:8000"}
ATTEMPTS = 4  # a cap: a 500 that lasts is the site's problem, not yours


def fetch(url):
    wait = 1.0
    for attempt in range(1, ATTEMPTS + 1):
        r = requests.get(url, proxies=PROXIES, timeout=20)
        if r.status_code in (403, 429):
            raise RuntimeError(f"{url}: HTTP {r.status_code} is a block or a rate limit, not a server error")
        if r.status_code < 500:
            return r
        print(f"attempt {attempt}: HTTP {r.status_code} {r.reason}, body: {r.text.strip()[:60]!r}")
        if attempt < ATTEMPTS:
            time.sleep(wait)
            wait *= 2  # 1 s, 2 s, 4 s
    raise RuntimeError(f"{url}: HTTP 500 after {ATTEMPTS} attempts, skip it and come back later")


r = fetch(URL)
print(f"HTTP {r.status_code}: {r.text.strip()}")

خروجی برای /flaky:

text
attempt 1: HTTP 500 Internal Server Error, body: '{"error":"database connection lost"}'
attempt 2: HTTP 500 Internal Server Error, body: '{"error":"database connection lost"}'
HTTP 200: ok

برای /text چهار تلاش چاپ می‌شود و اسکریپت با این سطر پایان می‌یابد:

text
RuntimeError: http://127.0.0.1:18500/text: HTTP 500 after 4 attempts, skip it and come back later

از طریق پروکسی، PROXIES را با آدرسی که سازنده نقطه اتصال نشان می‌دهد پر کنید؛ منطق تغییری نمی‌کند، چون 500 از مقصد می‌آید. اینکه کدام کدها را باید دوباره تلاش کرد و روی کدام‌ها متوقف شد، از 403 تا 504، در کدهای وضعیت HTTP در وب اسکرپینگ: 403، 407، 429، 503 آمده است.

کجا ممکن است با 500 روبه‌رو شوید

  • یک ⁦"500 Internal Server Error"⁩ ساده با nginx زیر آن در سایتی کوچک، اغلب درست پس از به‌روزرسانی سیستم مدیریت محتوا یا PHP آن.
  • درون برنامه‌ای مانند دیسکورد یا برنامه یک بانک، که صفحه‌هایش API خود سرویس را فرا می‌خوانند و عددی را که برگشته نشان می‌دهند.
  • پیام ⁦"The call failed on the server; see server log for details"⁩ در یک برنامه وب جاوا: متن ثابتی که چارچوب GWT وقتی فراخوانی سرور شکست می‌خورد همراه با 500 می‌فرستد.

اشتباه‌های رایج

  • بارگذاری دوباره در هر ثانیه. برنامه همین حالا هم شکست می‌خورد؛ درخواست‌های بیشتر آن را کندتر می‌کنند و لحظه بازگشتش را پنهان می‌کنند.
  • صاحبان سایت: بالا بردن memory_limit بدون خواندن لاگ. محدودیت بالاتر یک نشت حافظه را یک هفته پنهان می‌کند، سپس 500 برمی‌گردد.
  • صاحبان سایت: نشان دادن ردیابی پشته به بازدیدکنندگان. حالت اشکال‌زدایی که در محیط عملیاتی روشن مانده، مسیر فایل‌ها و جزئیات پایگاه داده را روی صفحه خطا چاپ می‌کند.
  • اسکرپرها: عوض کردن آی‌پی هنگام 500. سایت برای همه آدرس‌ها شکست می‌خورد؛ با فاصله دوباره تلاش کنید یا از صفحه بگذرید.

راهنمای انتخاب

وضعیت شماچه کنید
یک صفحه 500 نشان می‌دهد، بقیه سایت کار می‌کندیک بار دوباره بارگذاری کنید، چند دقیقه بعد دوباره امتحان کنید، صفحه را گزارش دهید
کل سایت در گوشی شما هم شکست می‌خوردسایت از کار افتاده است؛ صبر کنید یا صفحه وضعیت آن را ببینید
سایت شما، درست پس از به‌روزرسانی یا استقرارتغییر را برگردانید، سپس لاگ خطا را بخوانید
سایت شما، لاگ می‌گوید ⁦"Allowed memory size"⁩memory_limit را یک بار بالا ببرید، سپس کدی را که به آن نیاز دارد درست کنید
اسکریپت شما از یک سایت 500 می‌گیرد3 تا 4 بار با فاصله‌هایی که بلندتر می‌شوند تلاش کنید، سپس بگذرید و هم‌زمانی را کم کنید

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

آیا خطای ⁦500 Internal Server Error⁩ تقصیر من است؟

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

خطای 500 چقدر طول می‌کشد؟

زمان ثابتی ندارد. یک راه‌اندازی دوباره یا وقفه کوتاه پایگاه داده در چند ثانیه برطرف می‌شود؛ یک به‌روزرسانی خراب یا فایل .htaccess معیوب تا وقتی صاحب سایت متوجه شود و درستش کند می‌ماند.

⁦"500 Internal Server Error nginx"⁩ یعنی چه؟

nginx برنامه وب‌سرور جلوی سایت است و این صفحه، صفحه خطای کلی آن: برنامه پشت nginx شکست خورده و nginx پاسخ درستی برای رساندن نداشته است.

پیام ⁦"The call failed on the server; see server log for details"⁩ یعنی چه؟

متن ثابتی است که چارچوب GWT، که برخی برنامه‌های وب جاوا از آن استفاده می‌کنند، وقتی درخواستی به سرور خطا می‌دهد همراه با وضعیت 500 می‌فرستد. لاگی را که به آن اشاره می‌کند فقط گردانندگان سایت می‌توانند بخوانند؛ برای شما یک 500 معمولی است.

چرا دیسکورد یا برنامه دیگری خطای 500 نشان می‌دهد؟

برنامه‌ها داده‌های خود را از طریق API سرویس می‌گیرند و وقتی API با 500 پاسخ می‌دهد، برنامه همان عدد را نشان می‌دهد. قطعی در سمت سرویس است؛ صفحه وضعیت آن را ببینید و بعداً امتحان کنید.

آیا پاک کردن کوکی‌ها خطای 500 را رفع می‌کند؟

گاهی، وقتی برنامه روی یک کوکی یا نشست کهنه گیر می‌کند. آن را فقط پس از بارگذاری دوباره و صبر کردن امتحان کنید؛ بیشتر خطاهای 500 در سرور هستند و پاک کردن داده‌ها اثری بر آن‌ها ندارد.

خلاصه

خطای ⁦500 Internal Server Error⁩ یعنی برنامه سایت به مشکلی خورده که نتوانسته از پس آن برآید و سرور به جای صفحه یک خطای کلی فرستاده است. بازدیدکننده‌ها یک بار دوباره بارگذاری می‌کنند، صبر می‌کنند و از دستگاه دیگری آزمایش می‌کنند؛ صاحبان سایت لاگ خطا را می‌خوانند و از آخرین تغییر، افزونه‌ها، .htaccess، محدودیت‌های PHP و مجوزها به عقب برمی‌گردند؛ اسکریپت‌ها با فاصله‌هایی که بلندتر می‌شوند دوباره تلاش می‌کنند و هرگز با آدرس‌های تازه فشار نمی‌آورند. انواع پروکسی را می‌توانید در صفحه پروکسی ما مقایسه کنید.

پرسش از ChatGPTپرسش از Claude