รหัสข้อผิดพลาด Claude API: วิธีแก้ 401/403/404/429/529 ฉบับครบ
รหัสข้อผิดพลาด Claude API: วิธีแก้ 401/403/404/429/529 ฉบับครบ
ตีสามทุ่ม pipeline ขึ้นสถานะแดงทั้งสาย ใน log มีแค่บรรทัดเดียวคือ authentication_error — นี่คือฉากที่คนทั่วไปที่ใช้ Claude API คุ้นเคย ข่าวดีคือ API error มีความแม่นยำ: แต่ละรหัสบอกชัดว่าปัญหาอยู่ชั้นไหน บทความนี้แยกห้า error ที่เจอบ่อยที่สุดของ Claude API ออกมาทีละตัว: ความหมาย สาเหตุที่พบบ่อย วิธีแก้ และลำดับการตรวจสอบที่ตายตัว
หน้าตาของ error response
นิยาม: API สไตล์ Anthropic คืน JSON โครงสร้างเดียวกันเวลาพัง: type ชั้นบนเป็น error, error.type ชั้นในเป็นหมวดที่เครื่องอ่านได้ (เช่น authentication_error) และ error.message เป็นคำอธิบายสำหรับคน ให้อ่าน error.type ก่อนเสมอ เพราะมันระบุจุดพังแม่นกว่าสถานะ code ลอย ๆ
{
"type": "error",
"error": {
"type": "authentication_error",
"message": "invalid x-api-key"
}
}
รายละเอียดจากการทดสอบจริง
ผ่าน gateway นั้น ความล้มเหลวด้าน auth อาจถูกดักก่อนส่งต่อ ตัว body ที่ได้อาจเป็นข้อความสั้น (เช่น 401 ที่ตอบแค่ Invalid token) แทน JSON เต็ม วิธีเช็ก: ลองซ้ำด้วย key ที่ถูกต้องหนึ่งครั้ง ถ้าผ่านแปลว่า endpoint กับ path ปกติ ปัญหาเดิมอยู่ที่ชั้น key
401 authentication_error: ชั้น key
สาเหตุ: ไม่ส่ง key ไปกับ request / key สะกดผิด / key ถูกเพิกถอน / หรือตัวแปรเก่าทับค่าใหม่
วิธีแก้: ยืนยันว่า key ถูกส่งด้วย header x-api-key และไม่มีช่องว่างเกิน → รัน echo $ANTHROPIC_API_KEY เช็กค่าใน shell ปัจจุบัน → สร้าง key ใหม่ใน console เทียบกัน ถ้า key ใหม่ผ่านแปลว่าตัวเก่าตายจริง
401 ที่เจอบ่อยที่สุด
การ unset ตัวแปรเก่าตัวเดียว แก้ 401 ได้เกินครึ่ง ตัวแปรใน shell ชนะ config file เสมอ — ถ้ามีสองที่ ให้ใช้ค่าจาก shell
403 permission_error: ชั้นสิทธิ์
สาเหตุ: key ถูกต้องแต่ไม่มีสิทธิ์เข้าถึงทรัพยากร — พบบ่อยสุดคือ key ถูกจำกัดกลุ่มโมเดล หรือบัญชีถูกระงับ
วิธีแก้: 403 ต่างจาก 401 ตรงที่ "key ถูกแต่สิทธิ์ไม่พอ" เช็กสถานะบัญชีก่อน แล้วเช็กว่าโมเดลเป้าหมายอยู่ในขอบเขตของ key ไหม ถ้าผ่าน gateway ให้ดูว่า gateway จำกัดโมเดลนั้นไหม แล้วเปลี่ยนโมเดลหรือปรับใน console
404 not_found_error: path กับชื่อโมเดล
สาเหตุ: สองกรณี — path ผิด หรือ model ID ไม่มีจริง
เช็ก path: endpoint ทางการคือ https://api.anthropic.com/v1/messages; ผ่าน EXAIV คือ https://exaiv.com/api/ai/v1/anthropic/v1/messages ที่เจอบ่อยคือเอา path สไตล์ OpenAI (/v1/chat/completions) มาใช้กับโปรโตคอล Anthropic หรือลืม /v1
เช็ก model name: claude-opus-4-8 กับ ID จริงต่างกันตัวอักษรเดียวก็ 404 ทันที รายการโมเดลให้ยึดฝั่ง endpoint — ดูได้ที่หน้าโมเดล
429 rate_limit_error: ชั้น rate limit
สาเหตุ: ความถี่หรือ concurrency เกินโควตา นี่ไม่ใช่ปัญหา แต่คือสัญญาณว่า "ตอนนี้ต้องช้าลง"
วิธีแก้: อ่าน retry-after ใน response แล้วรอตาม → ทำ exponential backoff: รอ 1 วินาทีแล้ว 2, 4, 8 พร้อมสุ่ม jitter กัน request พร้อมกันหมด → ระยะยาวลด concurrency หรือใส่ token bucket ฝั่ง client
429 ต่างจาก 529 อย่างไร
429 คือ "คุณเร็วไป" ผิดที่ฝั่งเรียก แก้ด้วยการถอยหลัง; 529 คือ "ของฝั่งบนล้น" ไม่ผิดที่ฝั่งเรียก แก้ด้วยการรอ — ทั้งคู่ไม่มีทางแก้ด้วยการรีทันที
529 overloaded_error: ของฝั่งบนล้น
สาเหตุ: upstream overloaded ชั่วคราว รับ request ใหม่ไม่ไหวในเวลาที่กำหนด เป็น code เฉพาะของ Claude (OpenAI ไม่มีค่าตรงกัน) และจะถูกส่งต่อผ่าน compatible endpoint มาเหมือนเดิม
วิธีแก้: exponential backoff มักหายในไม่กี่วินาทีถึงสิบกว่าวินาที สายงานที่แคร์ความต่อเนื่อง ให้ตั้ง fallback model ไว้ — นั่นคือประโยชน์หลักของการใช้ gateway: เปลี่ยนโมเดลคือเปลี่ยน string เดียว ไม่ต้องขอ key ใหม่
โค้ดอื่นแบบสั้น
| Code | error.type | ความหมาย | จัดการ |
|---|---|---|---|
| 400 | invalid_request_error | body/พารามิเตอร์ผิด | อ่าน message; มักเป็น max_tokens หายหรือ messages ผิดรูป |
| 413 | request_too_large | body ใหญ่เกิน | ย่อ context หรือแบ่งเอกสาร |
| 500 | api_error | upstream error ภายใน | ถอยหลัง retry; เจอซ้ำค่อยสืบ |
ลำดับการตรวจ: ครั้งละหนึ่งชั้น
| ชั้น | เช็ก | เครื่องมือ |
|---|---|---|
| ① key | ค่าปัจจุบันใน shell / ถูกเพิกถอนไหม | echo $ANTHROPIC_API_KEY |
| ② URL | path ครบ (มี /v1) ไหม | เทียบหัวข้อ 404 ด้านบน |
| ③ model ID | เทียบทีละตัวอักษรกับรายการ | หน้าโมเดล |
| ④ rate/overload | สถานะ 429/529 | ถอยหลังแล้ว retry |
| ⑤ network | proxy / firewall | ลองคนละเครือข่าย |
เทคนิคที่ประหยัดเวลาที่สุด: ยิง endpoint ด้วย curl เปล่าก่อนแตะโค้ดแอป ถ้า curl ผ่านแต่โค้ดไม่ผ่าน ปัญหาอยู่ฝั่ง client ถ้า curl ก็ไม่ผ่าน ให้เดินตารางด้านบน — วิธีนี้ย่อเวลา debug เฉลี่ยจากครึ่งชั่วโมงเหลือไม่ถึงห้านาที
ห่อครั้งเดียว: request helper ที่รองรับ retry
แทนที่จะโรยตรรกะ retry ทุกจุดเรียก ให้ห่อ endpoint ครั้งเดียวแล้วให้ทุกฟีเจอร์ได้ใช้ต่อ helper ที่ดีทำสี่อย่างตามลำดับ: ส่งด้วย key และ URL เต็ม, จัดประเภทความล้มเหลวจาก error.type (authentication/permission ไม่ควร retry, rate กับ overload ควร retry), ใช้ exponential backoff พร้อม jitter เฉพาะกลุ่มที่ retry ได้จนถึงจำนวนครั้งสูงสุด, และรายงาน error สุดท้ายพร้อม model ID กับจำนวนครั้งที่ลองเพื่อให้ log อธิบายตัวเองได้
ทีมที่ใช้แพตเทิร์นนี้จะได้ประโยชน์แฝง: เมื่อมีหมวด error ใหม่เกิดขึ้นฝั่ง upstream ตารางจัดประเภทอยู่ในที่เดียว การแก้จะไปถึงทุกจุดที่เรียกใช้พร้อมกัน และ helper ตัวเดียวกันยังเป็นที่พักตามธรรมชาติของ timeout budget ราย environment — สั้นสำหรับงาน interactive, ยาวสำหรับ batch — โดยไม่ต้องแตะจุดเรียกอีก
มอนิเตอร์: เปลี่ยน error เป็น dashboard
นับ error แยกตาม error.type ตามเวลา จะเปลี่ยนบทความนี้เป็น dashboard งาน operations ได้ สามชุดพอสำหรับทีมส่วนใหญ่: authentication error (ควรเป็นศูนย์นิ่ง ๆ — พุ่งเมื่อไหร่แปลว่ามี key รั่วหรือถูกหมุนเวียนที่ใดที่หนึ่ง), rate-limit error (เส้นโค้งวางแผนความจุของคุณ) และ 529/500 (สุขภาพ upstream จากมุมมองของคุณ) แจ้งเตือนกับชุดแรก, พยากรณ์ด้วยชุดที่สอง, และเรียกคนเฉพาะเมื่อชุดที่สามล้มต่อเนื่อง
จุดละเอียดเมื่อผ่าน gateway: auth rejection ฝั่ง gateway ปรากฏเป็น 401 ข้อความสั้น ไม่ใช่ JSON envelope ให้ parse แบบป้องกัน — ถือว่าทุก non-2xx เป็น error event แล้วจัดประเภทจากรูปร่างของ body ไม่ใช่โครงสร้างที่สมมติไว้ จะทำให้ dashboard ซื่อสัตย์ทั้งเส้นตรงและเส้น gateway