แก้ Redirect Loop ERR_TOO_MANY_REDIRECTS บน Hosting

คุณเปิดเว็บแล้วเจอข้อความ "ERR_TOO_MANY_REDIRECTS" หรือ "หน้าเว็บนี้เปลี่ยนเส้นทางหลายครั้งเกินไป" ปัญหานี้เรียกว่า Redirect Loop และพบบ่อยมากหลังย้ายเว็บ ติดตั้ง SSL หรือเปิดใช้ Cloudflare บทความนี้จะอธิบายสาเหตุและวิธีแก้ทีละกรณีให้จบในที่เดียว

Redirect Loop คืออะไร

Redirect Loop คืออาการที่เบราว์เซอร์ถูกส่งต่อ (redirect) ไปมาระหว่าง URL จนวนซ้ำไม่รู้จบ เช่น A ส่งไป B แล้ว B ส่งกลับมา A วนแบบนี้ตลอด เบราว์เซอร์มีลิมิตการ redirect (ปกติราว 20 ครั้ง) เมื่อเกินจะหยุดและแสดง ERR_TOO_MANY_REDIRECTS แทนการโหลดหน้าเว็บ สาเหตุเกือบทั้งหมดมาจากการตั้งค่า redirect ที่ขัดแย้งกันเองในระดับเซิร์ฟเวอร์หรือแอปพลิเคชัน

สาเหตุที่พบบ่อยที่สุด

เจาะลึกสาเหตุที่พบบ่อยทีละข้อ

ก่อนจะลงมือแก้ ควรเข้าใจว่าแต่ละสาเหตุเกิดจากอะไร เพราะ Redirect Loop เกือบทุกครั้งเกิดจาก "สองฝั่งเข้าใจไม่ตรงกัน" ว่าควรเสิร์ฟด้วย HTTP หรือ HTTPS, www หรือ non-www เมื่อสองชั้น (เช่น Cloudflare กับเซิร์ฟเวอร์ หรือ .htaccess กับปลั๊กอิน) ต่างฝ่ายต่างพยายาม redirect ไปคนละทาง คำขอจึงถูกโยนไปมาไม่จบ มาดูทีละกรณีว่าเกิดได้อย่างไรและสังเกตอย่างไร

Cloudflare SSL โหมด Flexible

นี่คือสาเหตุอันดับหนึ่งที่เจอบ่อยที่สุด เมื่อตั้ง SSL/TLS เป็นโหมด Flexible Cloudflare จะรับคำขอจากผู้ใช้เป็น HTTPS แต่ไปคุยกับเซิร์ฟเวอร์ต้นทาง (origin) ด้วย HTTP ธรรมดา ทีนี้ถ้าเซิร์ฟเวอร์ของคุณมีกฎ "ถ้าเข้ามาด้วย HTTP ให้ redirect ไป HTTPS" เซิร์ฟเวอร์จะเห็นว่า Cloudflare ส่งมาด้วย HTTP จึงสั่ง redirect กลับไป HTTPS แต่พอ Cloudflare รับ HTTPS แล้วก็แปลงเป็น HTTP ส่งกลับมาอีก วนแบบนี้ไม่รู้จบ สังเกตได้ว่า loop หายเมื่อปิด Cloudflare (DNS แบบเมฆเทา) แต่กลับมาเมื่อเปิด proxy (เมฆส้ม) มักชี้ไปที่ปัญหา SSL mode นี้

กฎ .htaccess ซ้อนทับกัน

หลายเว็บมีกฎ redirect หลายชุดสะสมมาเรื่อย ๆ เช่น ชุดหนึ่งบังคับ www อีกชุดบังคับ non-www หรือชุดหนึ่งบังคับ HTTPS แต่เขียนเงื่อนไขไม่รัดกุมจน redirect ทับซ้อนกับกฎอื่น ปัญหานี้พบมากหลังติดตั้งปลั๊กอิน, ย้ายโฮสต์, หรือก็อปกฎจากเว็บอื่นมาแปะโดยไม่ลบของเก่า ผลคือ A → B แล้ว B → A ทันที

WordPress Site URL ตั้งค่าผิด

ค่า siteurl และ home ในฐานข้อมูล WordPress บอกว่าเว็บควรอยู่ที่ URL ไหน ถ้าตั้งเป็น https:// ทั้งที่เซิร์ฟเวอร์ยังไม่ส่ง HTTPS จริง (หรือ Cloudflare เป็น Flexible) WordPress จะพยายาม redirect ทุกคำขอไป HTTPS ส่วนเซิร์ฟเวอร์ก็มองว่าเป็น HTTP จึงตีกลับ เกิด loop เช่นกัน อาการเด่นคือหน้าเว็บปกติเปิดได้แต่ /wp-admin วน หรือกลับกัน

www กับ non-www ชนกัน

ถ้าตั้งให้ www.yourdomain.com redirect ไป yourdomain.com พร้อมกับมีอีกกฎ (หรือการตั้งค่าใน CMS) ที่ดัน yourdomain.com กลับไป www สองกฎนี้จะขัดกันเอง คำขอจะเด้งไปมาระหว่างสองโดเมนจนเบราว์เซอร์ยอมแพ้ ทางแก้คือเลือกฝั่งเดียวให้ชัดเจนแล้วลบกฎตรงข้ามทิ้ง

วิธีแก้ทีละกรณี

กรณีที่ 1 — ตรวจ .htaccess ก่อน

เปิด File Manager ใน DirectAdmin แล้วดูไฟล์ .htaccess ที่ public_html ถ้าพบ rule บังคับ www และ non-www พร้อมกัน ให้เหลือไว้ทิศทางเดียว ตัวอย่าง rule บังคับ non-www + HTTPS ที่ถูกต้องและไม่วนลูป:

RewriteEngine On RewriteCond %{HTTPS} off [OR] RewriteCond %{HTTP_HOST} ^www\. [NC] RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC] RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301]

หัวใจคือต้องมีเงื่อนไขครบในกฎเดียว ไม่ใช่เขียนแยกหลายบล็อกที่ส่งกลับไปกลับมา

กรณีที่ 2 — WordPress

ถ้าเป็นเว็บ WordPress ให้ตรวจค่า Site URL ในฐานข้อมูล ผ่าน phpMyAdmin เปิดตาราง wp_options ดูแถว siteurl และ home ให้ตรงกัน (เป็น https ทั้งคู่ถ้าจะใช้ SSL) หรือเพิ่มบรรทัดนี้ใน wp-config.php เพื่อล็อกค่าไว้:

define('WP_HOME','https://yourdomain.com'); define('WP_SITEURL','https://yourdomain.com');

กรณีที่ 3 — Cloudflare

ถ้าใช้ Cloudflare เข้าไปที่ SSL/TLS → Overview แล้วเปลี่ยนโหมดจาก Flexible เป็น Full หรือ Full (strict) เพราะ Flexible จะให้ Cloudflare คุยกับเซิร์ฟเวอร์ด้วย HTTP ขณะที่เซิร์ฟเวอร์บังคับ HTTPS จึงวนลูป — โหมด Full จะให้คุยกันด้วย HTTPS ตรงกัน

กรณีที่ 4 — ล้าง Cookie และ Cache

หลังแก้ฝั่งเซิร์ฟเวอร์แล้ว ให้ล้าง cookie และ cache ของเบราว์เซอร์สำหรับโดเมนนั้น หรือทดสอบด้วยหน้าต่าง Incognito เพื่อยืนยันว่า loop หายจริง

เคล็ดลับ: เปิด Developer Tools (กด F12) แล้วไปแท็บ Network ติ๊ก "Preserve log" จะเห็นชัดว่า URL ไหน redirect ไป URL ไหน ช่วยชี้จุดที่วนลูปได้ภายในไม่กี่วินาที

ใช้ Developer Tools และ curl ดู Redirect Chain

วิธีที่เร็วที่สุดในการหาจุดที่วนลูปคือ "ดูลูกโซ่การ redirect" (redirect chain) ว่าคำขอถูกส่งต่อไปที่ไหนบ้างตามลำดับ มีสองเครื่องมือหลักที่ช่วยได้ทันที

ดูจาก Developer Tools ในเบราว์เซอร์

กด F12 เพื่อเปิด Developer Tools แล้วไปที่แท็บ Network ติ๊กช่อง Preserve log เพื่อไม่ให้ log หายเมื่อหน้าถูก redirect จากนั้นพิมพ์ URL เว็บแล้ว Enter คุณจะเห็นรายการคำขอเรียงต่อกัน แต่ละแถวที่มีสถานะ 301 หรือ 302 คือการ redirect หนึ่งครั้ง คลิกที่แถวนั้นแล้วดูหัวข้อ Location ใน Response Headers จะบอกว่าถูกส่งต่อไป URL ไหน ถ้าเห็น URL ปลายทางวนกลับมาที่ค่าเดิมซ้ำ ๆ นั่นคือจุดที่ loop เกิด

ตรวจด้วย curl จาก command line

ถ้าถนัด command line คำสั่ง curl ให้ภาพ redirect chain ที่ชัดเจนและไม่โดน cache เบราว์เซอร์รบกวน ใช้แฟล็ก -I เพื่อดูเฉพาะ header และ -L เพื่อให้ตามทุก redirect:

curl -sIL https://yourdomain.com | grep -i -E "^(HTTP|Location)"

ผลลัพธ์จะแสดงสถานะและ Location: ของแต่ละ hop ถ้าเป็น loop คุณจะเห็น Location สลับไปมาระหว่าง URL เดิมไม่จบ และ curl จะหยุดเองพร้อมขึ้นข้อความ Maximum (50) redirects followed ตัวอย่างผลลัพธ์ที่เป็น loop:

HTTP/2 301 location: https://www.yourdomain.com/ HTTP/2 301 location: https://yourdomain.com/ HTTP/2 301 location: https://www.yourdomain.com/ curl: (47) Maximum (50) redirects followed

จากตัวอย่างนี้เห็นชัดว่า yourdomain.com กับ www.yourdomain.com ดันกันไปมา แปลว่ามีกฎ www/non-www ขัดกันสองชุด ต้องเหลือไว้ทิศทางเดียว ถ้าอยากเห็นจำนวน hop และเวลาแต่ละขั้น ใช้รูปแบบนี้ได้:

curl -sIL -w "%{num_redirects} hops, http %{http_code}\n" -o /dev/null https://yourdomain.com

การอ่าน redirect chain ให้ออกคือทักษะสำคัญที่สุดในการแก้ปัญหานี้ เพราะเมื่อรู้ว่า URL ไหนชี้ไป URL ไหน คุณจะตามรอยกลับไปยังกฎที่ผิดได้ทันที แทนที่จะเดาสุ่มแก้ทีละจุด

วิธีป้องกันไม่ให้เกิดซ้ำ

หมายเหตุ: Hosting ของ AsiaGB ใช้ DirectAdmin ที่จัดการ Let's Encrypt SSL ให้อัตโนมัติ เมื่อ origin มีใบเซอร์จริงและตั้ง Cloudflare เป็น Full (strict) โอกาสเกิด Redirect Loop จาก SSL mismatch จะแทบเป็นศูนย์

คำถามที่พบบ่อย

ERR_TOO_MANY_REDIRECTS คืออะไร?

ERR_TOO_MANY_REDIRECTS หรือ Redirect Loop คืออาการที่เบราว์เซอร์ถูกส่งต่อไปมาระหว่าง URL จนวนซ้ำไม่รู้จบ เบราว์เซอร์จึงหยุดและแสดง error แทน มักเกิดจากการตั้งค่า .htaccess, WordPress siteurl หรือ SSL ที่ขัดแย้งกัน

Cloudflare Flexible SSL ทำให้เกิด Redirect Loop ได้อย่างไร?

เมื่อตั้ง Cloudflare เป็นโหมด Flexible Cloudflare จะเชื่อมต่อเซิร์ฟเวอร์ด้วย HTTP แต่เซิร์ฟเวอร์มี rule บังคับ redirect HTTP ไป HTTPS ทำให้วนลูปไม่รู้จบ แก้โดยเปลี่ยน SSL/TLS mode เป็น Full หรือ Full (strict)

ล้าง Redirect Loop โดยไม่แก้เซิร์ฟเวอร์ได้ไหม?

ลองล้าง cookie และ cache ของเบราว์เซอร์สำหรับโดเมนนั้นก่อน บางครั้ง loop เกิดจาก cookie เก่าที่ค้าง แต่ถ้าสาเหตุอยู่ที่ .htaccess หรือ WordPress ต้องแก้ที่ฝั่งเซิร์ฟเวอร์จึงจะหายถาวร

ทำไม Redirect Loop เกิดเฉพาะหน้า wp-admin?

ถ้า loop เกิดเฉพาะหน้า /wp-admin มักมาจากปลั๊กอินบังคับ HTTPS หรือค่า FORCE_SSL_ADMIN ใน wp-config.php ที่ขัดแย้งกับการที่เซิร์ฟเวอร์ไม่ได้ส่ง header HTTPS จริง ให้ปิดปลั๊กอินชั่วคราวและตรวจค่า FORCE_SSL_ADMIN ก่อน

ใช้ curl ตรวจ Redirect Loop อย่างไร?

ใช้คำสั่ง curl -sIL https://yourdomain.com แล้วดูบรรทัด Location: ในแต่ละ hop ถ้าเห็น URL ปลายทางวนกลับมาที่เดิมซ้ำ ๆ แสดงว่ามี loop curl จะหยุดเองเมื่อ redirect เกินลิมิตและรายงาน error ออกมา

Hosting ที่จัดการ SSL และ .htaccess ให้ครบ

AsiaGB Web Hosting มาพร้อม SSL Let's Encrypt ฟรี, DirectAdmin และทีมซัพพอร์ตภาษาไทยช่วยแก้ปัญหา redirect ให้ เริ่มต้น 500 บาท/ปี

ดูแพ็กเกจ Hosting