คำตอบสั้น ๆ: รู้ความหมายของ HTTP Error 403, 404, 500, 502, 503 และ 504 สาเหตุที่พบจริง และวิธีไล่หาต้นตอจาก Log ของ Nginx, Apache และ PHP-FPM
คู่มือนี้อธิบาย Error ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
เมื่อเบราว์เซอร์ขอหน้าเว็บ เซิร์ฟเวอร์จะตอบกลับพร้อมรหัสสถานะ (HTTP Status Code) สามหลักเสมอ รหัสกลุ่ม 2xx คือสำเร็จ 3xx คือให้ไปที่อื่น 4xx คือคำขอมีปัญหาหรือไม่ได้รับอนุญาต และ 5xx คือเซิร์ฟเวอร์มีปัญหา การรู้ความหมายของรหัสช่วยให้รู้ทันทีว่าควรไปดูที่ไหน ไม่ต้องเดาสุ่ม
บทความนี้อธิบายรหัสที่เจอบ่อยที่สุดหกรหัส ได้แก่ 403, 404, 500, 502, 503 และ 504 พร้อมสาเหตุที่พบจริงและวิธีไล่หาต้นตอบนเว็บที่ใช้ Nginx, Apache, PHP-FPM, Plesk และ DirectAdmin
สิ่งที่ต้องเตรียม
- URL ที่เกิดปัญหา และเวลาที่เกิด (ใช้ค้นใน Log)
- สิทธิ์ดู Log ของเว็บ ผ่านแผงควบคุม หรือ SSH ที่ใช้
sudoได้ - คำสั่ง
curlสำหรับดูรหัสสถานะที่แท้จริง
ขั้นตอนที่ 1: ดูรหัสสถานะที่แท้จริง
หน้า Error ที่เห็นในเบราว์เซอร์อาจถูกแต่งโดยธีม CDN หรือเบราว์เซอร์เอง ให้ดูรหัสจริงด้วย
curl -sI https://example.com/some-page/
บรรทัดแรกคือรหัสสถานะ เช่น HTTP/2 502 ดู Header server: ประกอบ ถ้าเป็น cloudflare แปลว่าคำตอบมาจาก CDN ต้องแยกให้ออกว่าปัญหาอยู่ที่ CDN หรือเซิร์ฟเวอร์ต้นทาง ใน DevTools ของเบราว์เซอร์ดูได้ที่แท็บ Network คอลัมน์ Status
ขั้นตอนที่ 2: รู้ว่า Log อยู่ที่ไหน
| ระบบ | Error Log |
|---|---|
| Nginx (Ubuntu, AlmaLinux/Rocky) | /var/log/nginx/error.log |
| Apache บน Ubuntu | /var/log/apache2/error.log |
| Apache บน AlmaLinux/Rocky | /var/log/httpd/error_log |
| PHP-FPM บน Ubuntu 24.04 | /var/log/php8.3-fpm.log (22.04 ใช้ php8.1-fpm.log) |
| PHP-FPM บน AlmaLinux/Rocky | /var/log/php-fpm/error.log และ www-error.log |
| Plesk | Websites & Domains > โดเมน > Logs (ดู ดู Log เว็บไซต์บน Plesk เพื่อหาสาเหตุ Error) |
| DirectAdmin | หน้า Site Summary / Statistics / Logs ของโดเมน (ชื่อเมนูต่างกันตามเวอร์ชัน) |
ดู Log แบบ Real-time ขณะเปิดหน้าที่มีปัญหา
sudo tail -f /var/log/nginx/error.log
ถ้าเว็บตั้ง Log แยกต่อโดเมน ชื่อไฟล์จะอยู่ในไฟล์ตั้งค่า Virtual Host หรือ Server Block (error_log หรือ ErrorLog)
ขั้นตอนที่ 3: ความหมายและวิธีแก้แต่ละรหัส
403 Forbidden: เซิร์ฟเวอร์เข้าใจคำขอ แต่ไม่อนุญาต
สาเหตุที่พบบ่อย
- สิทธิ์ไฟล์ผิด: Web Server อ่านไฟล์หรือเข้าโฟลเดอร์ไม่ได้ Log มักเขียนว่า
Permission deniedค่าทั่วไปคือโฟลเดอร์755ไฟล์644ดู ทำความเข้าใจสิทธิ์ไฟล์บน Linux ด้วย chmod และ chown - ไม่มีไฟล์ index: เปิดโฟลเดอร์ที่ไม่มี
index.htmlหรือindex.phpและปิด Directory Listing ไว้ Nginx จะเขียนว่าdirectory index of ... is forbidden - กฎปฏิเสธการเข้าถึง:
.htaccessมีRequire all deniedหรือdenyของ Nginx, หรือ IP ถูก Firewall, ModSecurity, Fail2ban หรือปลั๊กอินความปลอดภัยบล็อก - SELinux (AlmaLinux/Rocky): สิทธิ์ไฟล์ถูกต้องแต่ยัง 403 เพราะ Context ของไฟล์ไม่ถูกต้อง ดู ใช้งาน SELinux บน AlmaLinux และ Rocky Linux โดยไม่ต้องปิด
404 Not Found: ไม่มีสิ่งที่ขอ
ถ้าเกิดกับทุกหน้าย่อยของ WordPress หลังเปลี่ยน Permalink หรือย้ายโฮสต์ เป็นเรื่องกฎ Rewrite ดู แก้ปัญหาหน้าเว็บ 404 หลังตั้ง Permalink ใน WordPress ถ้าเกิดเฉพาะบางหน้าที่เคยมี แปลว่าหน้าถูกลบหรือเปลี่ยน URL ควรทำ 301 Redirect ไปหน้าที่ใกล้เคียงที่สุด (ดู ทำ 301 Redirect ด้วยไฟล์ .htaccess หรือ ทำ 301 Redirect บน Nginx) รายงาน Pages ใน Google Search Console ช่วยหา URL ที่ Google เจอว่าเป็น 404 ได้ อย่าลืมว่า 404 สำหรับหน้าที่ไม่มีอยู่จริงเป็นเรื่องปกติและถูกต้อง ไม่ต้อง Redirect ทุก URL ไปหน้าแรก
500 Internal Server Error: แอปพลิเคชันหรือการตั้งค่าผิดพลาด
เป็นรหัสกว้างที่สุด แปลว่าเกิดข้อผิดพลาดที่ไม่ได้ระบุ ต้องอ่าน Log เสมอ สาเหตุที่พบบ่อย
- PHP Fatal Error: ปลั๊กอินหรือธีมไม่รองรับเวอร์ชัน PHP, หน่วยความจำไม่พอ (
Allowed memory size exhausted) ดู แก้ปัญหา "There has been a critical error" ใน WordPress ด้วย WP_DEBUG และ เพิ่ม Memory Limit ใน WordPress - ไวยากรณ์ .htaccess ผิด: Apache Log จะเขียน
Invalid commandหรือInvalid RewriteRuleให้คืนไฟล์ก่อนแก้ - สิทธิ์ไฟล์ของสคริปต์: บางระบบ (เช่น suEXEC/PHP-CGI) ไม่ยอมรันไฟล์ที่เขียนได้โดยทุกคน (
777)
502 Bad Gateway: ตัวกลางติดต่อบริการด้านหลังไม่ได้
Nginx หรือ Proxy ส่งต่อคำขอไปให้บริการด้านหลัง (PHP-FPM, Node.js, Apache) แล้วได้คำตอบที่ใช้ไม่ได้หรือเชื่อมต่อไม่ได้เลย Log ของ Nginx มักเขียนว่า connect() failed (111: Connection refused) หรือ No such file or directory ที่ชี้ไปยังไฟล์ Socket
# Ubuntu 24.04 (เปลี่ยนเวอร์ชันตามที่ติดตั้ง)
sudo systemctl status php8.3-fpm
# AlmaLinux / Rocky
sudo systemctl status php-fpm
ถ้าสถานะไม่ใช่ active (running) ให้สั่ง restart แล้วดูสาเหตุที่หยุดใน journalctl -u ของบริการนั้น (ดู อ่าน Log ระบบบน Linux ด้วย journalctl) ถ้าบริการทำงานอยู่ ให้ตรวจว่า fastcgi_pass ใน Nginx ชี้ไปที่ Socket เดียวกับค่า listen ใน Pool ของ PHP-FPM ปัญหานี้เกิดบ่อยหลังอัปเกรด PHP เพราะชื่อ Socket เปลี่ยนตามเวอร์ชัน (ดู ติดตั้ง PHP หลายเวอร์ชันบน Ubuntu) สำหรับแอป Node.js ให้ตรวจว่าแอปยังรันอยู่บนพอร์ตที่ proxy_pass ชี้ไป
503 Service Unavailable: บริการยังไม่พร้อมชั่วคราว
- WordPress ค้างโหมด Maintenance: การอัปเดตถูกขัดจังหวะ ทำให้ไฟล์
.maintenanceค้างอยู่ในโฟลเดอร์รากของเว็บ หน้าเว็บจะแสดง "Briefly unavailable for scheduled maintenance" ลบไฟล์นั้นออกแล้วตรวจว่าปลั๊กอินที่กำลังอัปเดตครบถ้วน - ถึงขีดจำกัดของบริการ: เช่น Rate Limit ของ Nginx (
limit_reqตอบ 503 โดยค่าเริ่มต้น) หรือขีดจำกัดทรัพยากรของบัญชีโฮสติ้ง - ตั้งใจปิดปรับปรุง: ถ้าปิดเว็บเพื่อซ่อมบำรุง การตอบ 503 พร้อม Header
Retry-Afterคือวิธีที่ถูกต้อง Google จะกลับมาใหม่โดยไม่ลบหน้าออกจากดัชนี ถ้าเป็นช่วงสั้นๆ
504 Gateway Timeout: บริการด้านหลังตอบช้าเกินกำหนด
ต่างจาก 502 ตรงที่เชื่อมต่อได้ แต่รอคำตอบนานเกินเวลาที่ตั้งไว้ (ค่าเริ่มต้นของ Nginx คือ 60 วินาที) Log ของ Nginx จะเขียนว่า upstream timed out (110: Connection timed out) สาเหตุคือสคริปต์ทำงานนาน เช่น นำเข้าข้อมูล สร้างรายงาน หรือ Query ฐานข้อมูลที่ช้า หรือเซิร์ฟเวอร์ทรัพยากรเต็ม
แนวทางที่ถูกคือหาว่าทำไมช้า (ดู เปิด Slow Query Log เพื่อหา Query ที่ทำให้ฐานข้อมูลช้า และ ตรวจสอบ CPU, RAM และ Load Average ของ Linux Server) ถ้าเป็นงานที่ต้องใช้เวลานานจริงและยอมรับได้ ค่อยเพิ่มเวลารอเฉพาะจุด เช่นใน Server Block
location ~ \.php$ {
# ... ค่าเดิม ...
fastcgi_read_timeout 180s;
}
และต้องเพิ่มค่าเวลาของ PHP ให้สอดคล้องกัน (max_execution_time และ request_terminate_timeout ของ Pool ถ้าตั้งไว้) บน Plesk ดู ปรับค่า PHP (memory_limit, max_execution_time) บน Plesk ถ้าใช้ proxy_pass ค่าที่ต้องปรับคือ proxy_read_timeout งานที่ใช้เวลานานมากควรย้ายไปทำเป็นงานเบื้องหลังผ่าน Cronjob แทน