HTTP Status Codes

18HTTP Status Codes — full reference

What you will master here

  • Every status class (1xx, 2xx, 3xx, 4xx, 5xx) and the codes that matter
  • Methods (GET / POST / PUT / PATCH / DELETE / HEAD / OPTIONS) and idempotency
  • The headers SDETs actually use
  • Caching: ETag, Cache-Control, If-None-Match, If-Modified-Since
  • CORS preflight (OPTIONS) — what triggers it and how to debug

18.1 1xx — Informational

CodeMeaningNotes
100 ContinueServer received headers, send the bodyUsed with Expect: 100-continue for large uploads
101 Switching ProtocolsUpgrading to WebSocket / HTTP/2Returned during WS handshake
103 Early HintsPreload hints before final responseModern perf optimization

18.2 2xx — Success

CodeMeaningCommon usage
200 OKGeneric successGET response with body, PUT/PATCH success
201 CreatedNew resource createdPOST that creates; often returns Location header
202 AcceptedRequest accepted, processing asyncReturns job id; client polls for completion
204 No ContentSuccess, no bodyDELETE response, PUT without body
206 Partial ContentRange request fulfilledVideo streaming, resumable downloads

18.3 3xx — Redirection

CodeMeaningSDET notes
301 Moved PermanentlyURL changed foreverSEO + browser caches the redirect
302 FoundTemporary redirectLogin → dashboard, classic flow
303 See OtherPOST-redirect-GET patternTells client to use GET on the new URL
304 Not ModifiedCached version still validReturned when If-None-Match matches ETag
307 Temporary RedirectLike 302 but preserves the methodPOST stays POST after redirect
308 Permanent RedirectLike 301 but preserves methodNewer, replaces 301 in REST APIs

18.4 4xx — Client error

CodeMeaningTest scenarios
400 Bad RequestMalformed requestBad JSON, missing required field
401 UnauthorizedNo or invalid credentialsMissing token, expired token
402 Payment RequiredReserved (some APIs use it)Stripe-style billing errors
403 ForbiddenAuthenticated, not allowedRBAC failure, user hitting /admin
404 Not FoundResource doesn't existBad id, deleted resource
405 Method Not AllowedWrong HTTP verb for this URLPOST to a GET-only endpoint
406 Not AcceptableServer can't satisfy Accept headerClient asked for XML, server only does JSON
408 Request TimeoutClient didn't finish sendingSlow client or network
409 ConflictState conflictDuplicate email signup, version conflict (ETag)
410 GoneResource permanently removedUsed for deprecated endpoints
411 Length RequiredMissing Content-LengthRare; some APIs strict on it
413 Payload Too LargeBody bigger than server allowsFile upload size limit
414 URI Too LongURL exceeds server limitMassive query strings
415 Unsupported Media TypeWrong Content-TypeSending XML to a JSON-only endpoint
418 I'm a teapotApril Fools' jokeReal RFC; some APIs use it as easter egg
422 Unprocessable EntityValidation failed on parsed bodyBody parsed but fields invalid (Rails default)
425 Too EarlyServer unwilling to risk replay attack0-RTT TLS edge case
426 Upgrade RequiredMust use a different protocolHTTP/1.1 →HTTP/2 forced
428 Precondition RequiredServer requires conditional headersForces If-Match / If-Unmodified-Since
429 Too Many RequestsRate limitedReturns Retry-After, X-RateLimit-Remaining
431 Request Header Fields Too LargeHeaders exceed limitBloated cookies / auth headers
451 Unavailable For Legal ReasonsCensorship / DMCAGeo / content block

18.5 5xx — Server error

CodeMeaningCommon cause
500 Internal Server ErrorUnhandled exceptionThe bug you file. Server should not show stack to client.
501 Not ImplementedServer doesn't support methodTRACE on locked-down APIs
502 Bad GatewayUpstream service returned bad responseMicroservice chain failure, proxy issue
503 Service UnavailableTemporarily down / overloadedMaintenance, autoscaler scaling up
504 Gateway TimeoutUpstream took too longSlow downstream, network partition
505 HTTP Version Not SupportedClient sent unsupported HTTP versionVery rare
507 Insufficient StorageServer out of diskStorage backend full
508 Loop DetectedInfinite redirect / proxy loopMisconfigured CDN
511 Network Authentication RequiredCaptive portalWi-Fi needs sign-in

18.6 HTTP Methods + idempotency

MethodPurposeSafeIdempotentCacheable
GETRetrieve resource
HEADHeaders only, no body
OPTIONSDiscover allowed methods, CORS preflight
POSTCreate / submitonly if explicit
PUTReplace
PATCHPartial updatenot required
DELETERemove
TRACEEcho for diagnostics
CONNECTSet up tunnel (HTTPS via proxy)

Safe: doesn't modify server state. Idempotent: calling N times has same effect as 1 time. Idempotent methods can be safely retried by clients on network errors — non-idempotent (POST) can't without an idempotency key.

18.7 Headers SDETs actually use

Request headers

HeaderPurpose
AcceptWhat content types the client wants back (application/json)
Accept-LanguagePreferred languages (en-US,en;q=0.9)
Accept-EncodingCompression accepted (gzip, br)
AuthorizationCredentials — Bearer, Basic, etc.
Content-TypeWhat format the request body is in
Content-LengthBody size in bytes
CookieCookies sent to server
If-None-MatchETag — return 304 if unchanged
If-Modified-SinceTime-based conditional GET
OriginOrigin of cross-origin request (CORS)
RefererThe page that initiated the request
User-AgentBrowser / client identifier
X-Requested-WithConventional "XMLHttpRequest" marker
Idempotency-KeyClient-generated, lets server dedupe retries

Response headers

HeaderPurpose
Content-TypeFormat of the response body
Content-LengthBody size
Cache-ControlCache rules (no-store, public, max-age=3600)
ETagOpaque version id of the resource
Last-ModifiedWhen the resource was last changed
LocationURL to redirect to / location of created resource
Set-CookieCookies for the browser to store
Retry-AfterSeconds (or HTTP date) until client should retry
X-RateLimit-Limit / Remaining / ResetRate limit window state
WWW-AuthenticateHow to authenticate (returned with 401)
Strict-Transport-SecurityHSTS — force HTTPS
Content-Security-PolicyWhat resources the page may load
X-Frame-OptionsPrevent embedding in iframe
Access-Control-Allow-OriginCORS — who can access

18.8 Caching with ETag

# First request
GET /api/products/42
<-- 200 OK
    ETag: "v3"
    Cache-Control: max-age=60
    {... body ...}

# Second request, within max-age
GET /api/products/42
    If-None-Match: "v3"
<-- 304 Not Modified
    (no body — client uses cached version)

18.9 CORS preflight (OPTIONS)

Browsers send a preflight OPTIONS request before a "non-simple" cross-origin request (custom headers, non-GET/HEAD/POST, etc.). The server's response decides whether the actual request is allowed.

OPTIONS /api/orders HTTP/1.1
    Origin: https://app.example.com
    Access-Control-Request-Method: POST
    Access-Control-Request-Headers: authorization, content-type

<-- 204
    Access-Control-Allow-Origin: https://app.example.com
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE
    Access-Control-Allow-Headers: authorization, content-type
    Access-Control-Max-Age: 600
Common bugMisconfigured CORS = "fetch failed in browser" but works in Postman. Postman doesn't enforce CORS — only browsers do. Always test from a real origin.

Module 25 — HTTP Q&A bank

200 vs 201 vs 204?
200 — generic success with body (GET, PUT). 201 — new resource created (POST), often returns Location. 204 — success with no body (DELETE, no-body PUT).
301 vs 302 vs 307 vs 308?
301 permanent (cached forever, method may change to GET). 302 temporary (method may change). 307 temporary, preserves method. 308 permanent, preserves method. Use 307/308 for REST APIs to keep POST as POST.
What is 304 Not Modified?
Response to a conditional GET (If-None-Match with ETag, or If-Modified-Since). Server says "your cached copy is still valid, here are no bytes". Saves bandwidth.
401 vs 403?
401 — server doesn't know who you are (no/expired/invalid credentials). 403 — server knows who you are, but you're not allowed (RBAC denied).
400 vs 422?
400 — request couldn't be parsed (malformed JSON, missing required header). 422 — parsed fine but the data is semantically invalid (email field is not an email). Rails/Django often use 422; others may use 400 for both.
What does 429 mean and what headers come with it?
429 Too Many Requests — rate limited. Server typically returns Retry-After (seconds until you can retry) and X-RateLimit-Limit/Remaining/Reset. Honour them; don't retry tight-loop.
502 vs 504?
502 Bad Gateway — upstream service returned an invalid response. 504 Gateway Timeout — upstream didn't respond within the gateway's timeout. Both point to issues behind your direct server.
What is idempotency?
Calling an operation N times has the same effect as calling it once. GET, PUT, DELETE are idempotent; POST is not (each POST may create a new resource). Idempotent calls are safe to retry on network errors.
How do you make POST idempotent?
Idempotency-Key header — client generates a UUID, sends it with each retry of the same logical operation. Server caches the response under that key; retries return the cached response instead of duplicating the side effect.
What is PUT vs PATCH?
PUT replaces the resource entirely with the body (missing fields become null/default). PATCH applies a partial change — only fields in the body are updated.
What's a CORS preflight?
An OPTIONS request the browser sends before a "non-simple" cross-origin request to check if the server allows it. Server returns Access-Control-Allow-Origin / Methods / Headers; if those match the intended request, browser sends the real request.
Why does my fetch fail in the browser but work in Postman?
CORS. Browsers enforce same-origin policy and refuse cross-origin requests unless the server explicitly allows them. Postman is not a browser and doesn't enforce CORS. Configure CORS on the server (Access-Control-Allow-Origin) for the browser origin.
What's HEAD for?
Like GET but server returns only headers, no body. Useful for checking existence, content-length, last-modified, or content-type without downloading.
What's the difference between Cookie and Set-Cookie?
Set-Cookie is a server response header telling the browser to store a cookie. Cookie is a request header where the browser sends previously-stored cookies back. Sessions ride on this pair.
What's Cache-Control: no-store vs no-cache?
no-store: don't cache at all (sensitive data). no-cache: may cache but must revalidate with the server before using. Often confused — no-cache still allows caching, just with a freshness check.
What's an ETag?
Opaque version identifier (string) the server attaches to a resource. Client sends it back in If-None-Match on subsequent requests; server returns 304 if unchanged. Enables efficient cache validation without timestamps.
HTTP/1.1 vs HTTP/2 — key difference for SDETs?
HTTP/2 multiplexes many requests over one TCP connection — no head-of-line blocking, lower latency on busy pages. Most production sites use HTTP/2 today. Tests rarely care, but slow-network simulation should reflect realistic behaviour.
What is HSTS?
HTTP Strict Transport Security — server response header that tells browsers "always use HTTPS for this domain for the next N seconds". Prevents downgrade attacks. Use Strict-Transport-Security: max-age=31536000; includeSubDomains; preload.