یک صفحه حذف شده، API پرداخت Timeout داده و CDN هنوز نسخه Cache را تحویل میدهد. هر سه درخواست ممکن است برای کاربر «خراب» به نظر برسند، اما پاسخ درست آنها یکی نیست. انتخاب اشتباه کد وضعیت HTTP میتواند Browser و Crawler را گمراه کند، Retry تکراری بسازد، Cache را آلوده کند یا Incident واقعی را پشت یک ۲۰۰ ظاهراً سالم پنهان نگه دارد.
کدهای وضعیت HTTP نتیجه پردازش یک Request را در سطح پروتکل بیان میکنند؛ نه کیفیت کسبوکار، رضایت کاربر یا موفقیت نهایی Workflow را. این راهنما معنای 1xx تا 5xx را بر پایه RFC، رفتار مرتبط Google، کاربرد API و وبسایت، Cache، Retry، مانیتورینگ و Runbook رفع خطا توضیح میدهد. مثالها عملیاند و برای تیمهای محصول، توسعه، DevOps و سئو در ایران نیز ملاحظات شبکه و سرویس ثالث را پوشش میدهند.
کد وضعیت HTTP چیست؟
کلاینت—Browser، App، Bot یا سرویس دیگر—یک Method و Target را همراه Header و گاهی Body میفرستد. Server یا یک Intermediary مانند CDN، Reverse proxy یا Gateway پاسخی شامل Status code، Header و احتمالاً Content برمیگرداند. استاندارد اصلی RFC 9110: HTTP Semantics معناهای Method، Status و Fieldهای مشترک را تعریف میکند.
کد سهرقمی یک Contract فشرده است:
- رقم اول، کلاس کلی پاسخ را مشخص میکند؛
- کد دقیق، معنای استاندارد نتیجه را میدهد؛
- Headerهایی مانند
Location،Allow،WWW-Authenticate،Retry-AfterوCache-Controlرفتار بعدی را کامل میکنند؛ - Body برای انسان یا ماشین جزئیات میآورد، اما نباید با Status تناقض داشته باشد.
| کلاس | معنای کلی | پرسش اپراتور | نمونه |
|---|---|---|---|
| 1xx | پاسخ میانی/اطلاعاتی | آیا Exchange هنوز ادامه دارد؟ | ۱۰۰، ۱۰۱، ۱۰۳ |
| 2xx | Request طبق معنای Method موفق بود | چه Resource/نتیجهای ساخته یا برگردانده شد؟ | ۲۰۰، ۲۰۱، ۲۰۲، ۲۰۴، ۲۰۶ |
| 3xx | برای تکمیل یا استفاده از Cache اقدام دیگری لازم است | دائمی است، موقت یا Revalidation؟ | ۳۰۱، ۳۰۲، ۳۰۳، ۳۰۴، ۳۰۷، ۳۰۸ |
| 4xx | Request فعلی از دید Server قابل انجام نیست | Client چه چیزی را باید اصلاح یا مجاز کند؟ | ۴۰۰، ۴۰۱، ۴۰۳، ۴۰۴، ۴۰۹، ۴۲۲، ۴۲۹ |
| 5xx | Server/Upstream در انجام Request معتبر شکست خورد | کدام Dependency و آیا Retry امن است؟ | ۵۰۰، ۵۰۲، ۵۰۳، ۵۰۴ |
Status code بهتنهایی کافی نیست
Method بخشی از معناست
200 برای GET با Body، 201 برای ساخت Resource و 204 برای موفقیت بدون Content میتواند درست باشد. همان عدد بدون دانستن Method ناقص است. GET و HEAD و دیگر Methodهای Safe برای بازیابیاند؛ PUT و DELETE از نظر Semantics استاندارد Idempotentاند؛ POST بهصورت پیشفرض چنین تضمینی ندارد. پیادهسازی باید واقعاً با Contract هماهنگ باشد.
HTTP success با Business success یکی نیست
اگر Server سالم یک درخواست نامعتبر پرداخت را رد کند، 4xx میتواند پاسخ عملیاتی صحیح باشد. اگر API همیشه 200 بدهد و خطا را در {"success":false} پنهان کند، Proxy، Alert، SDK و داشبورد کلاس Status را اشتباه میفهمند. در مقابل، یک 200 واقعی نیز تضمین نمیکند HTML مفید، داده تازه یا Outcome کاربر درست باشد. Latency و تجربه کاربر Contract جداگانهای دارند؛ برای اتصال آنها به نتیجه کسبوکار، راهنمای سرعت سایت و سنجش اثر را ببینید.
ممکن است اصلاً Status نداشته باشیم
خطای DNS، TLS، Connection reset، Timeout پیش از پاسخ یا قطع شبکه Status code HTTP ندارد. Monitoring نباید همه Failureها را در «۵۰۰» ادغام کند. راهنمای رسمی خطاهای DNS و شبکه برای Crawlerهای گوگل نیز این Failureها را از پاسخ HTTP جدا میکند، هرچند اثر Crawl آنها میتواند شبیه 5xx باشد.
| لایه | Failure نمونه | آیا Status داریم؟ | شاهد لازم |
|---|---|---|---|
| DNS/TLS | Resolution، Certificate، Handshake | معمولاً خیر | Probe، Resolver/TLS log |
| CDN/Edge | Rule، WAF، Cache، Edge timeout | بله یا Vendor code | Edge status و Ray/Request ID |
| Gateway | Route، Auth، Rate limit | بله | Gateway log و upstream_status |
| Application | Validation، Conflict، Bug | بله | Normalized route، trace و error type |
| Dependency | DB، Queue، API ثالث | در Upstream بله/خیر | Span، timeout و retry count |
| Business | پرداخت ناموفق، Lead ردشده | وابسته به Contract | Domain status و Backend record |
کدهای 1xx؛ پاسخهای میانی
پاسخ 1xx نهایی نیست و Exchange ادامه دارد. کاربران معمولاً آن را نمیبینند، اما Client، Proxy و Server باید Semantics آن را درست اجرا کنند.
| کد | معنا | کاربرد | نکته عملی |
|---|---|---|---|
| 100 Continue | Client میتواند Body مورد انتظار را ادامه دهد | Request بزرگ با Expect: 100-continue | همه مسیرهای Proxy یکسان رفتار نمیکنند؛ تست End-to-end لازم است |
| 101 Switching Protocols | تغییر Protocol طبق Upgrade پذیرفته شد | مثلاً Upgrade در HTTP/۱.۱ | WebSocket روی HTTP/۲/۳ Mechanics متفاوتی دارد؛ نسخه را لحاظ کنید |
| 103 Early Hints | Hintهای اولیه پیش از پاسخ نهایی | Preload Resourceهای Critical | بر اساس RFC 8297 است؛ جای Cache policy یا اندازهگیری Field را نمیگیرد |
کدهای 2xx؛ موفقیت در سطح HTTP
| کد | زمان استفاده | Header/Body مورد انتظار | خطای رایج |
|---|---|---|---|
| 200 OK | عملیات موفق و Representation/نتیجه آماده است | Content متناسب با Method و Content-Type | بازگرداندن صفحه خطا یا JSON failure با ۲۰۰ |
| 201 Created | Resource جدید ساخته شده است | ترجیحاً Location و Representation/شناسه | ۲۰۱ پیش از Commit واقعی |
| 202 Accepted | پردازش پذیرفته اما تمام نشده | Job ID، Status URL، State و زمانبندی تقریبی | جا زدن Accepted بهعنوان Success نهایی |
| 204 No Content | عملیات موفق و Body لازم نیست | بدون Content؛ Headerها همچنان معنا دارند | دادن ۲۰۴ به صفحهای که باید HTML قابل پردازش داشته باشد |
| 206 Partial Content | پاسخ به Range معتبر | Content-Range و Semantics Range | پاسخ ناقص بدون Header صحیح |
200 «کد ایدهآل همه URLها» نیست. URL منتقلشده باید Redirect، Resource حذفشده ۴۰۴/۴۱۰، و Service موقتاً unavailable معمولاً ۵۰۳ برگرداند. همین صداقت باعث میشود Browser، Bot و Monitor تصمیم مناسب بگیرند. برای طراحی HTTP API از صفر، راهنمای API، قرارداد و قابلیت اطمینان را ببینید.
کدهای 3xx؛ Redirect و Revalidation
همه 3xxها «تغییر مسیر» به یک معنا نیستند. ۳۰۴ اصلاً انتقال به URL دیگر نیست؛ پاسخ Conditional request است. تفاوت مهم دیگر، موقتی/دائمی بودن و حفظ Method است.
| کد | نوع | رفتار Method | کاربرد نمونه |
|---|---|---|---|
| 301 Moved Permanently | دائمی | Clientهای تاریخی ممکن است POST را به GET تبدیل کنند | انتقال دائمی صفحه/URL |
| 302 Found | موقت | Clientهای تاریخی ممکن است Method را تغییر دهند | مقصد موقت |
| 303 See Other | ارجاع به نتیجه با GET/HEAD | بازیابی مقصد با GET/HEAD | Post/Redirect/Get |
| 304 Not Modified | Revalidation | برای Conditional GET/HEAD | استفاده از Representation ذخیرهشده |
| 307 Temporary Redirect | موقت | Method و Content حفظ میشود | انتقال موقت حساس به Method |
| 308 Permanent Redirect | دائمی | Method و Content حفظ میشود | انتقال دائمی حساس به Method |
ریدایرکت برای سئو؛ دائمی در برابر موقت
در Google Search، ۳۰۱/۳۰۸ سمت Server سیگنال قوی دائمی برای Canonical target و ۳۰۲/۳۰۳/۳۰۷ سیگنال موقتاند. راهنمای جاری Redirect و Google Search این تفاوت را توضیح میدهد. «۳۰۲ هیچ اعتباری منتقل نمیکند» یا «۳۰۱ رتبه را تضمین میکند» هر دو سادهسازی غلطاند؛ Redirect فقط یکی از Signalهاست و مقصد باید معادل و قابل پردازش باشد.
زنجیره و Loop
هر Hop Latency، Failure point و Crawl request اضافه میکند. Ruleها را تا حد امکان Old→Final بسازید، HTTP→HTTPS و www/non-www را با انتقال محتوا در یک مسیر کوتاه حل کنید و Query لازم را آگاهانه حفظ نمایید. برای نقشه Migration و تست Ruleها، مقاله ریدایرکت ۳۰۱ و کاربردهای سئو را ببینید.
۳۰۴ بهتنهایی «بهبود سئو» نیست
۳۰۴ یعنی Validator نشان داده Representation ذخیرهشده قابل استفاده است. اثر واقعی به ETag یا Last-Modified، Cache-Control، Vary، Cache key و Client بستگی دارد. ۳۰۴ Body ندارد و جای پاسخ اولیه ۲۰۰ را نمیگیرد.
کدهای 4xx؛ Request فعلی قابل انجام نیست
نام «Client error» همیشه به معنای تقصیر کاربر نهایی نیست؛ لینک شکسته داخلی، Rule اشتباه WAF یا Contract ناقص API ممکن است مسئول باشد. پاسخ باید به Client بگوید چه چیزی قابل اصلاح است، بدون افشای اطلاعات حساس.
| کد | معنا/کاربرد | Header یا پاسخ مفید | مرز مهم |
|---|---|---|---|
| 400 Bad Request | Request قابل پردازش نیست | Error type و Fieldهای نامعتبر | با Validation دامنهای دقیقتر اشتباه نشود |
| 401 Unauthorized | Credentials معتبر ارائه نشده | WWW-Authenticate | نام تاریخی است؛ مسئله Authentication است |
| 403 Forbidden | Server درخواست را فهمیده و مجاز نمیداند | پیام حداقلی/مسیر درخواست دسترسی | ورود دوباره الزاماً مشکل را حل نمیکند |
| 404 Not Found | Resource یافت نشد یا وجودش آشکار نمیشود | صفحه مفید انسانی با Status واقعی ۴۰۴ | نباید همه 404ها به Home Redirect شوند |
| 405 Method Not Allowed | Method برای Resource پشتیبانی نمیشود | Allow | با ۴۰۴ Route اشتباه نشود |
| 408 Request Timeout | Server منتظر Request کامل ماند | پاسخ حداقلی | با ۵۰۴ Upstream timeout فرق دارد |
| 409 Conflict | تعارض با State فعلی Resource | Conflict type و راه Resolve | Version/duplicate/state transition |
| 410 Gone | Resource عمداً و دائماً حذف شده | توضیح انسانی اختیاری | جایگزین معادل داشت، Redirect بهتر است |
| 412 Precondition Failed | شرط If-Match/… برقرار نیست | Current validator | برای جلوگیری از Lost update مفید است |
| 413 Content Too Large | Payload بیش از حد قابل قبول | Limit مجاز | Limit را در Gateway و App هماهنگ کنید |
| 415 Unsupported Media Type | Content-Type/Encoding پشتیبانی نمیشود | Typeهای قابل قبول | با ۴۰۶ پاسخ قابل ارائه فرق دارد |
| 422 Unprocessable Content | Syntax فهمیده شده ولی دستور معتبر نیست | Field/domain errors | Contract تیم باید ۴۰۰/۴۲۲ را ثابت کند |
| 429 Too Many Requests | Rate limit این Client/Scope رد شده | ترجیحاً Retry-After و Limit context امن | Overload عمومی میتواند ۵۰۳ باشد |
| 451 Unavailable for Legal Reasons | دسترسی به علت تقاضای حقوقی محدود است | توضیح مجاز و مسئول | تنها با بررسی حقوقی |
۴۰۱، ۴۰۳ یا ۴۰۴؟
اگر Authentication لازم/نامعتبر است، ۴۰۱ همراه Challenge مناسب است. اگر هویت معلوم اما مجوز کافی نیست، ۴۰۳ رایج است. Server میتواند برای پنهانکردن وجود Resource حساس ۴۰۴ بدهد. این تصمیم بخشی از Threat model است؛ راهنمای امنیت API و OWASP مرز مجوز Function/Object/Property را پوشش میدهد.
۴۰۴ سالم و Soft ۴۰۴
صفحه انسانی ۴۰۴ میتواند Search، دستههای مهم و راه بازگشت داشته باشد، اما Header باید ۴۰۴ بماند. اگر Template خطا با 200 برگردد، Bot و Monitoring آن را Success میبینند؛ Google ممکن است آن را Soft ۴۰۴ تشخیص دهد. Redirect همه URLهای حذفشده به Home نیز مقصد نامرتبط و تجربه گمراهکننده میسازد.
۴۲۹ را با Retry storm بدتر نکنید
RFC 6585 کد ۴۲۹ را برای Too Many Requests تعریف میکند و امکان Retry-After را میدهد. Scope—API key، User، IP، Tenant یا Route—و Window باید در Contract روشن باشد. Client باید Backoff/Jitter و Retry budget داشته باشد؛ تلاش همزمان هزار Client بعد از یک زمان ثابت میتواند موج دوم بسازد.
کدهای 5xx؛ شکست Server یا Upstream
| کد | معنا | علت نمونه | اقدام نخست |
|---|---|---|---|
| 500 Internal Server Error | وضعیت غیرمنتظره مانع انجام Request شد | Bug، Exception، invariant شکستخورده | Trace/Correlation ID و Rollback/mitigate |
| 501 Not Implemented | Server قابلیت لازم برای انجام Method را ندارد | Method واقعاً پشتیبانینشده | Contract/Capability را اصلاح کنید |
| 502 Bad Gateway | Gateway از Upstream پاسخ نامعتبر گرفت | Protocol/TLS/connection/response malformed | edge→upstream chain را بررسی کنید |
| 503 Service Unavailable | Service موقتاً قادر به پردازش نیست | Maintenance، overload، dependency unavailable | Capacity/Dependency، Retry-After و degraded mode |
| 504 Gateway Timeout | Gateway پاسخ Upstream را بهموقع نگرفت | DB/API کند یا timeout budget نامتناسب | Trace deadline و upstream latency |
۵۰۲ و ۵۰۴ دقیقتر از «سرور Down است» هستند: یکی پاسخ Upstream نامعتبر و دیگری نبود پاسخ بهموقع در نقش Gateway است. ۵۰۰ را برای همه خطاها نریزید؛ 4xx معتبر را 5xx کردن Alert و Retry غلط میسازد. برعکس، Exception واقعی را با ۴۰۰ پنهان نکنید تا Error budget ظاهراً سبز بماند.
۵۰۳ برای Maintenance
صفحه Maintenance باید در Edge یا مسیر کموابستگی، با Status ۵۰۳ واقعی، پیام فارسی روشن، زمان/وضعیت بهروز و در صورت امکان Retry-After ارائه شود. ۲۰۰ با متن «برمیگردیم» معنای Success میدهد؛ Redirect دائمی نیز تصمیم Search را عوض میکند. ۵۰۳ طولانی بیاثر نیست و نیاز به Incident plan دارد.
Decision tree انتخاب Status برای URLهای سایت
| واقعیت URL | پاسخ مناسب | دلیل | QA |
|---|---|---|---|
| محتوا موجود و قابل ارائه است | 200 | Representation واقعی آماده است | Body، Canonical، Indexability جداگانه |
| به URL معادل دائمی منتقل شده | 301/308 | مقصد نهایی جایگزین است | یک Hop، ۲۰۰ Final و Self-canonical |
| مقصد موقت است | 302/307 | Source باید مرجع اصلی بماند | Method و Expiry |
| حذف و جایگزین معادل ندارد | ۴۰۴ یا ۴۱۰ | وجود نداشتن صادقانه | از Sitemap/لینک داخلی حذف |
| موقتاً به علت Maintenance/Overload در دسترس نیست | 503 | Failure سمت Service و موقت | Retry-After، Monitor، پایان Incident |
| کاربر Auth نشده | 401 | Challenge لازم است | WWW-Authenticate و عدم Cache عمومی |
| مجاز نیست | ۴۰۳ یا ۴۰۴ حفاظتی | Authorization/عدم افشای وجود | Threat model و Audit log |
| صفحه خطای SPA | ۴۰۴ واقعی یا مسیر قابل noindex | ۲۰۰ shell میتواند Soft ۴۰۴ بسازد | Rendered/public fetch |
اول Inventory و مقصد معادل را تصمیم بگیرید؛ سپس Rule بنویسید. «هر ۴۰۴ را Redirect کنیم» ضد الگوست. URL تایپی و Spam بینهایتاند و Redirect آنها به Home معنی ندارد. 404های دارای لینک داخلی، Backlink، ترافیک یا Journey مهم را اولویت دهید.
اثر کدهای HTTP بر Crawl و Index گوگل
رفتار Search engine بخشی از RFC نیست. مستند جاری اثر Status code بر Crawlerهای گوگل میگوید 2xx فقط محتوا را وارد مرحله پردازش میکند و تضمین Index نیست؛ ۲۰۴ محتوایی برای پردازش ندارد؛ Redirectها دنبال میشوند؛ 4xxها جز ۴۲۹ بهمرور از Index کنار میروند؛ و ۴۲۹/5xx باعث کاهش موقت Crawl میشوند و در صورت تداوم میتوانند به حذف URLهای Indexشده برسند.
۴۰۴ و ۴۱۰ برای Google Search
در مستند فعلی گوگل، همه 4xxهای رایج بهجز ۴۲۹ برای پردازش Search عملاً در خانواده نبود Content قرار میگیرند. بنابراین ادعای عمومی «۴۱۰ حتماً سریعتر از ۴۰۴ حذف میشود» مبنای عملی این راهنما نیست. ۴۱۰ را وقتی بفرستید که از حذف دائمی آگاهید؛ نه برای دستکاری سرعت Index.
۲۰۰ تضمین Index نیست
صفحه خالی، خطا با ۲۰۰، محتوای بسیار مشابه، noindex، Canonical به URL دیگر یا کیفیت/تقاضای ناکافی میتواند Index نشود. Status فقط Eligibility اولیه انتقال Content را بیان میکند. برای دید سراسری Crawl/Index/Canonical و تبدیل Findings به Roadmap، چکلیست ممیزی کامل سئو را استفاده کنید.
Crawl Stats را با Log ترکیب کنید
گزارش Crawl Stats سرچ کنسول Response class، Host status، DNS، robots.txt و Connectivity را نشان میدهد، اما فهرست URLهای نمونه جامع نیست. Server/CDN log منبع جزئیتر شماست. Redirect chain در Crawl Stats چند Request جدا میسازد؛ این یکی از دلایل کاهش Hopهاست.
Cache، ۳۰۴ و Negative caching
Cache فقط Browser نیست: CDN، Reverse proxy، Service worker، Application cache و Object cache هرکدام Key، TTL و Invalidation دارند. RFC 9111: HTTP Caching توضیح میدهد Cache میتواند علاوه بر ۲۰۰، Redirect، ۴۰۴ و ۲۰۶ را نیز با شرایط لازم ذخیره کند.
Revalidation با Validator
Server با ETag یا Last-Modified Validator میدهد؛ Client بعداً If-None-Match یا If-Modified-Since میفرستد. اگر نسخه مناسب همان است، ۳۰۴ بدون Content برمیگردد و Cache Representation قبلی را بهروزرسانی/استفاده میکند. ETag ضعیف/قوی و Vary باید با Encoding و Variant سازگار باشند.
۴۰۴ هم ممکن است Cache شود
Negative caching میتواند بار URLهای ناموجود را کم کند، اما پس از ایجاد Resource همان URL، TTL بلند باعث ادامه ۴۰۴ شود. Deploy و Purge را با Policy هماهنگ کنید. پاسخ Authenticated یا شخصی را بدون دستور صریح در Shared cache ذخیره نکنید. مقاله معماری Cache سایت لایهها، Cache key، TTL و Invalidation را عمیقتر توضیح میدهد.
| نشانه | احتمال | تست | اصلاح |
|---|---|---|---|
| Edge=۲۰۰، Origin=۵۰۳ | Stale/Cache hit | Age/Via/X-Cache + Origin probe | Degraded policy و Alert Origin |
| فقط بعضی کاربران ۴۰۴ | Negative cache/Variant key | POP، Vary، Cookie و purge status | Key/TTL/Purge |
| ۳۰۴ ولی Content قدیمی | Validator غلط | ETag/Last-Modified across variants | Generation و Vary |
| محتوای شخصی نشت کرده | Shared cache policy اشتباه | Auth/Cookie/Cache-Control review | private/no-store/key isolation |
قرارداد خطای API؛ Status + Problem type
Status class باید به SDK و Operator امکان تصمیم بدهد؛ Body باید به Client جزئیات ماشینخوان و امن بدهد. RFC 9457: Problem Details for HTTP APIs قالب استانداردی با Fieldهایی مانند type، status، title، detail و instance تعریف میکند. این قالب Debug dump نیست و نباید Stack، SQL، Secret یا شناسه قابل سوءاستفاده را افشا کند.
نمونه Contract مفهومی
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
{
"type": "https://api.example.ir/problems/invalid-amount",
"title": "مبلغ معتبر نیست",
"status": 422,
"detail": "مبلغ باید بر حسب ریال و بزرگتر از صفر باشد",
"instance": "/requests/req_7f3",
"errors": [{"field": "amount_irr", "code": "positive_required"}]
}در Production، instance یا Correlation ID باید قابل پیگیری برای پشتیبانی باشد و حداقل اطلاعات لازم را بدهد. متن فارسی برای انسان و Code پایدار برای ماشین نگه دارید. واحد ریال/تومان را در Field name و Contract صریح کنید.
Matrix ثابت بسازید
برای هر Endpoint و Error type بنویسید: Status، Problem type، Retryability، Idempotency requirement، User message، Log severity و Owner. ۴۰۹ Conflict، ۴۲۲ Validation، ۴۲۹ Limit و ۵۰۳ Dependency failure نباید همگی یک Error عمومی باشند.
Retry، Timeout و Idempotency
Retry تصمیم Client است، نه نتیجه خودکار هر 5xx. اگر POST پرداخت Timeout شود، Client نمیداند عملیات انجام شده یا نه. Retry کور میتواند سفارش/برداشت تکراری بسازد. Idempotency key، Unique constraint، Status lookup و Reconciliation باید پیش از Retry طراحی شوند.
| پاسخ/Failure | Retry معمولاً؟ | شرط | ضدالگو |
|---|---|---|---|
| 400/401/403/404/422 | بدون تغییر Request خیر | اصلاح Input/Auth/Permission | تکرار سریع همان Request |
| 408 | ممکن است | Method امن/Idempotent یا Key | فرض اینکه Server هیچ کاری نکرده |
| 409/412 | پس از Resolve | State/Version جدید | Overwrite کور |
| 429 | بله با محدودیت | Retry-After، Backoff، Jitter، Budget | Retry هماهنگ همه Clientها |
| 500 | وابسته | Error type و Idempotency | بینهایت Retry |
| 502/503/504 | اغلب موقت، نه همیشه | Deadline، Budget، Circuit breaker | ضربکردن بار Upstream |
| Network timeout | نامعلوم | Lookup/Reconcile + Key | تعبیر Timeout به Failure قطعی |
Timeout باید Budget انتهابهانتها داشته باشد؛ Timeout Gateway نباید کوتاهتر از مسیر منطقی بدون طراحی Async باشد یا آنقدر بلند شود که Queue و Connection را اشباع کند. Retry count، delay و outcome را در Trace ثبت کنید. در Workflow حساس، ۲۰۲ + Job status یا Queue قابل پیگیری از Request همزمان طولانی بهتر است.
CDN، Proxy و کدهای غیراستاندارد
کاربر ممکن است Status ساختهشده توسط CDN را ببیند نه Origin. Fieldهایی مانند Via یا Headerهای Vendor و مقادیر edge_status/origin_status در Log کمک میکنند. کدهایی مانند ۴۹۹ یا برخی 52xها در محصولات مشخص رایجاند اما بخشی از Registry عمومی HTTP نیستند؛ معنا را از مستند همان Vendor بگیرید و در Dashboard به یک 5xx مبهم له نکنید.
HEAD با GET یکسان فرض نشود؛ تست شود
طبق Semantics، HEAD باید Headerهای پاسخ GET معادل را بدون Content بازتاب دهد، اما Application/CDN گاهی Route متفاوت دارد. ابزارهایی که فقط HEAD میزنند ممکن است ۲۰۰ ببینند و GET واقعی ۵۰۰ شود یا برعکس. Monitor اصلی Journey باید GET و در عملیات نوشتنی Contract واقعی را تست کند.
Final response را همراه Chain ذخیره کنید
فقط Final ۲۰۰ کافی نیست. تعداد Hop، Status هر Hop، Location، زمان DNS/TLS/TTFB، POP، Cache status و Origin status را ثبت کنید. Redirect cross-domain، از دست رفتن Query یا Downgrade ناخواسته میتواند با Final ۲۰۰ پنهان بماند.
Observability و SLO برای Status codeها
نرخ 5xx کل سایت ممکن است سبز باشد، در حالی که Checkout برای اپراتور خاص کاملاً خراب است. Metric را بر Service، normalized route، Method، Region/ISP، Client type و Dependency Segment کنید؛ اما URL خام، User ID یا Query را Label نکنید چون Cardinality و Privacy را منفجر میکند.
RED و Outcome
- Rate: Request rate بر Route/Method؛
- Errors: 5xx، ۴۲۹، 4xx غیرمنتظره و Network failure؛
- Duration: Distribution و Tail latency، نه فقط Average؛
- Outcome: پرداخت/ثبت/انتشار واقعی و Reconciliation؛
- Saturation: Worker، Connection pool، Queue، CPU/Memory و Dependency.
چارچوب کامل Log/Metric/Trace، SLI/SLO و Alert burn-rate در راهنمای Observability و مانیتورینگ سایت آمده است.
| Signal | Field/Metric | هدف | هشدار |
|---|---|---|---|
| Request | request_id، trace_id، route، method | Correlation | Token/PII در Log نباشد |
| Response | status، bytes، latency | RED | Class + exact code |
| Proxy | edge_status، origin_status، cache_status | محل Failure | Final فقط کافی نیست |
| Dependency | upstream، timeout، retry_count | Root cause | Cardinality کنترل شود |
| Business | domain_outcome، reconciliation_state | اثر کاربر | از HTTP جدا ولی Correlated |
| Search | Googlebot class، Crawl Stats، Index sample | اثر Crawl | User-Agent spoof را حقیقت قطعی ندانید |
Alert بر نسبت و Budget، نه یک Request
یک ۵۰۰ منفرد شاید Noise و یک ۱٪ خطا در Checkout Severity بالا باشد. Alert را با SLO، Burn rate، حداقل Volume و Critical journey بسازید. Synthetic probe از چند مسیر شبکه، RUM و Backend health را ترکیب کنید. Alert باید Owner، Runbook، Severity و Silence policy داشته باشد.
Runbook رفع خطا
- Scope: کدام Route، Method، Region، ISP، Version، Client و زمان؟
- Layer: DNS/TLS، Edge، Gateway، App، DB یا سرویس ثالث؟
- Reality: Status واقعی GET، Body، Header، Chain و Outcome Backend چیست؟
- Change: Deploy، Config، Certificate، DNS، Campaign یا Traffic spike اخیر؟
- Mitigate: Rollback، Disable feature، Cache safe، Queue یا Degraded mode؟
- Communicate: پیام فارسی، Status page، ETA مشروط و کانال پشتیبانی؟
- Recover: Queue/Payment/Lead را Reconcile و Crawl/Index را نمونهگیری کنید.
- Learn: Timeline، Root cause، Contributing factors و اقدام دارای Owner/Deadline.
Priority 404
فهرست ۴۰۴ را با لینک داخلی، Sitemap، Backlink، Landing session، Revenue journey و تاریخ ایجاد غنی کنید. Internal link را اصلاح، Sitemap را پاک، معادل واقعی را Redirect و URL بیجایگزین را ۴۰۴/۴۱۰ نگه دارید. صفحه ۴۰۴ را از نظر Status، Mobile، Search و لینکهای کمکی تست کنید.
Priority 5xx
ابتدا Critical journey و Error budget، سپس Dependency/Version را جدا کنید. Correlation ID نمونه جمع کنید، ولی Log حساس را در Ticket عمومی نگذارید. پس از Recovery، Cache و Queue ممکن است Failure را ادامه دهند؛ End-to-end verify لازم است. بودجه کنترل و Trade-off امنیت/پایداری را در نقشه بودجه امنیت سایت میتوان ساختاری کرد.
امنیت و حریم خصوصی در پاسخ خطا
- Stack trace، مسیر فایل، Query دیتابیس، Secret، Token یا Policy داخلی را به Client ندهید.
- Correlation ID تصادفی و قابل جستوجو بدهید؛ جزئیات در Log محافظتشده بماند.
- ۴۰۴ حفاظتی را با Threat model انتخاب کنید و Enumeration timing را تست نمایید.
- Responseهای Auth را با Shared cache و Headerهای Cache-Control مرور کنید.
- Rate limit فقط IPمحور میتواند NAT و کاربران مشترک را ناعادلانه مسدود کند.
- WAF block را از Application ۴۰۳ جدا Log کنید.
- URL و Query ممکن است PII داشته باشد؛ Redaction، Retention و Access کنترل شود.
Status code کنترل امنیتی کامل نیست. ۴۰۱/۴۰۳ بدون Authorization درست، ۴۲۹ بدون Abuse control و پیام خطا بدون Logging امن مسئله را حل نمیکنند. Security review باید Failure mode و مسیر Recovery را نیز آزمایش کند.
ملاحظات عملی برای سایت ایرانی
یک Probe خارجی بهتنهایی تجربه کاربر داخل ایران را نشان نمیدهد و Probe داخلی نیز سلامت Origin جهانی را کامل نمیبیند. از نقاط مجاز و تحت مالکیت/قرارداد، چند ISP/Device و مسیر Edge/Origin را بسنجید. محدودیت یا Eligibility سرویس خارجی را تاریخدار ثبت کنید و راهکار را بر دورزدن بنا نکنید.
- پیام خطا فارسی و کوتاه، با Request ID، کانال پشتیبانی و زمان تهران؛
- نمایش تومان برای کاربر ولی واحد API/Payment صریح—مثلاً
amount_irr؛ - تست اعداد فارسی/لاتین، RTL/LTR و کپی کد خطا؛
- Fallback مجاز برای Captcha، Map، Font، Analytics و سرویس پیام؛
- تفکیک اختلال ISP/شبکه از Origin با Probe و Trace؛
- Status page کموابستگی و راه ارتباطی خارج از همان سامانه خراب؛
- تطبیق Timestamp UTC در Log با نمایش Asia/Tehran در Incident.
بهجای پیام «خطای ۵۰۰»، به کاربر بگویید درخواست ثبت نشده/وضعیت نامعلوم/در حال پردازش است و قدم امن بعدی چیست. برای پرداخت، هرگز Timeout را «ناموفق قطعی» ننامید تا Reconciliation انجام شود.
روش تست کد وضعیت و Headerها
تست Read-only زیر Header پاسخ GET را میبیند؛ ابزار را فقط روی مقصدی که مجاز به بررسی آن هستید اجرا کنید:
curl -sS -D - -o /dev/null \
--max-redirs 0 \
https://example.ir/old-pageبرای Chain، Redirect را آگاهانه Follow و هر Hop را ثبت کنید. Browser DevTools برای Client journey، Search Console URL Inspection برای نمای Google، Log برای Fleet و Synthetic monitor برای Availability مکملاند. یک Fetch دستی اثبات سلامت همه Regionها یا زمانها نیست.
| تست | چه چیزی را ثابت میکند؟ | چه چیزی را ثابت نمیکند؟ |
|---|---|---|
| curl GET/HEAD | Status/Header یک مسیر و لحظه | Browser render، Fleet و ISPهای دیگر |
| DevTools | Chain، Resource و Client errors | Bot/Backend outcome کامل |
| URL Inspection | Fetch/Render نمونه Google | Index تضمینی یا همه URLها |
| Crawl | الگوی Fleet از دید Crawler | Traffic/Business outcome |
| Server/CDN log | درخواست واقعی و لایه پاسخ | Perceived UX بدون RUM |
| Synthetic/RUM | Availability و تجربه مسیرها | علت بدون Trace/Log |
برنامه ۳۰ روزه اصلاح HTTP status
روز ۱ تا ۷: Inventory و Baseline
- Route/URL inventory، Method و Owner را استخراج کنید.
- Log Edge/Gateway/App و Search Console را بر Class و Route Baseline کنید.
- Critical journey، SLO و فهرست Statusهای مجاز/غیرمنتظره را بنویسید.
روز ۸ تا ۱۴: Contract و Triage
- Redirect map، ۴۰۴/۴۱۰ decision و Maintenance policy را تصویب کنید.
- Error catalog API، Problem type، Retryability و Security redaction را بسازید.
- Soft ۴۰۴، always-۲۰۰ API، chain/loop و robots.txt failure را اولویت دهید.
روز ۱۵ تا ۲۱: Fix و Observability
- Ruleها را در Staging با GET/HEAD/Methodهای واقعی و Cache تست کنید.
- edge/origin/upstream status، Correlation ID و Dashboard را اضافه کنید.
- Alert 5xx/۴۲۹، Synthetic journey و Runbook را اجرا و تمرین کنید.
روز ۲۲ تا ۳۰: Rollout و Verification
- Canary، Backup و Rollback؛ سپس Crawl و نمونه URL عمومی بگیرید.
- Sitemap، Internal links، Canonical و Final URLها را تطبیق دهید.
- Queue/Payment/Lead را Reconcile و Regressionها را ثبت کنید.
- Ownership و Review ماهانه/پس از هر Migration را در تقویم بگذارید.
چکلیست کدهای وضعیت HTTP
- □ هر Route و Method Statusهای مجاز و Owner دارد.
- □ HTTP success از Business outcome جدا اندازهگیری میشود.
- □ DNS/TLS/Timeout بدون Status در Telemetry دیده میشود.
- □ صفحه خطا با ۲۰۰ و API خطادارِ همیشه ۲۰۰ نداریم.
- □ ۲۰۱ پس از ساخت واقعی و ۲۰۲ با Job status استفاده میشود.
- □ ۲۰۴ هیچ Body/صفحه مورد انتظار را حذف نمیکند.
- □ Redirect دائمی/موقت و حفظ Method آگاهانه انتخاب شدهاند.
- □ Redirectها Old→Final، بدون Loop و با مقصد معادلاند.
- □ ۴۰۴ انسانی Status واقعی دارد و همه Missingها به Home نمیروند.
- □ ۴۰۱ با Challenge، ۴۰۳ با Authorization و ۴۰۴ حفاظتی با Threat model هماهنگاند.
- □ ۴۲۹/۵۰۳ در صورت مناسب Retry-After و Client backoff/jitter دارند.
- □ عملیات غیرIdempotent با Key، Lookup و Reconciliation محافظت میشود.
- □ ۳۰۴، Validator، Cache-Control، Vary و Cache key سازگارند.
- □ Negative cache و Purge پس از Deploy تست شده است.
- □ Error body ماشینخوان، پایدار، فارسیپذیر و بدون Secret/Stack است.
- □ Edge، Origin، Upstream و Domain outcome جدا ثبت میشوند.
- □ Dashboard بر Route/Method/Region و بدون Cardinality/PII خطرناک است.
- □ SLO، Alert burn-rate، Runbook، Status page و Rollback داریم.
- □ Sitemap فقط URL مناسب، و Internal link مقصد نهایی را دارد.
- □ Public GET، Browser، Crawl، Log و Backend outcome پس از تغییر تأیید شدهاند.
پرسشهای متداول کدهای وضعیت HTTP
تفاوت ۴۰۴ و ۵۰۳ چیست؟
۴۰۴ میگوید Resource این Request پیدا نشد یا وجودش افشا نمیشود؛ ۵۰۳ میگوید Service موقتاً قادر به پردازش نیست. برای صفحه حذفشده ۴۰۴/۴۱۰ و برای Maintenance/Overload موقت ۵۰۳ مناسبتر است. ۵۰۳ ماندگار نیز بیاثر نیست و باید Incident رفع شود.
آیا ۳۰۱ بهتر از ۳۰۲ است؟
«بهتر» نیست؛ معنای متفاوت دارد. اگر انتقال دائمی است ۳۰۱ یا ۳۰۸، و اگر موقت است ۳۰۲ یا ۳۰۷ بدهید. ۳۰۷/۳۰۸ Method را حفظ میکنند. برای Search، Redirect دائمی سیگنال قوی مقصد Canonical و Redirect موقت سیگنال ضعیف/موقت است؛ رتبه تضمین نمیشود.
آیا همه خطاهای ۴۰۴ را باید ریدایرکت کرد؟
خیر. فقط وقتی جایگزین واقعاً معادل یا انتقال واقعی وجود دارد Redirect کنید. URL حذفشده بیجایگزین باید ۴۰۴/۴۱۰ بماند. لینک داخلی و Sitemap را اصلاح کنید و 404های مهم را بر اساس Traffic، Backlink و Journey اولویت دهید.
آیا پاسخ ۲۰۰ یعنی صفحه ایندکس میشود؟
خیر. ۲۰۰ فقط Success در سطح HTTP و ارائه Content را بیان میکند. Google محتوا را برای پردازش در نظر میگیرد، اما Index به Content، Canonical، robots/noindex و عوامل دیگر وابسته است. صفحه خطا با ۲۰۰ ممکن است Soft ۴۰۴ تشخیص داده شود.
چه خطاهایی را میتوان Retry کرد؟
پاسخ ثابت وجود ندارد. ۴۲۹ و بعضی ۵۰۲/۵۰۳/504ها غالباً موقتاند، اما Retry باید با Retry-After، Backoff، Jitter، Deadline و Budget باشد. برای POST/پرداخت، Idempotency key و Reconciliation ضروری است؛ Timeout ثابت نمیکند عملیات انجام نشده است.
جمعبندی: کد وضعیت خوب فقط عدد درست نیست؛ ترکیب Method، Status، Header، Body، Cache، Retry و Telemetry است. Semantics را از RFC بگیرید، رفتار Google را جدا اجرا کنید، Reality را از Edge تا Backend ثبت کنید و برای هر Failure یک Owner و Runbook داشته باشید.






