HTTP API SRE Networking
HTTP Status Codes: The Complete Reference Guide
Onur Ömer Tunç 8 min read
1xx — Informational
| Code | Name | What it means |
|---|---|---|
| 100 | Continue | Server received the request headers; client may send the body. Used with Expect: 100-continue for large file uploads. |
| 101 | Switching Protocols | Protocol switch approved. Returned during HTTP → WebSocket upgrades (Upgrade: websocket). |
| 102 | Processing | WebDAV: server is processing the request, no response yet. Prevents timeouts on long-running operations. |
| 103 | Early Hints | Link headers sent before the final response. Used at CDN and edge to preload critical resources. |
SRE note: Seeing 101 in Kubernetes ingress logs for WebSocket connections is normal. For nginx ingress, don't forget
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" and proxy-send-timeout: "3600" — otherwise the ingress will cut the connection.
2xx — Successful
| Code | Name | What it means |
|---|---|---|
| 200 | OK | Standard success response. Body content varies by method: GET → resource, POST → operation result, PUT → updated resource. |
| 201 | Created | Resource created. The Location header should contain the URI of the new resource. Used with POST and PUT. |
| 202 | Accepted | Request received; processing continues asynchronously. Used for job/queue operations that can't return a result immediately. |
| 203 | Non-Authoritative Information | Response was modified by a proxy or cache. Metadata may differ from the origin. |
| 204 | No Content | Success with no body. Standard for DELETE and some PUT operations. |
| 205 | Reset Content | Client should reset the form or view. Used in browser form resets. |
| 206 | Partial Content | Partial content returned via Range header. Used for large file downloads, video streaming, and resumable downloads. |
| 207 | Multi-Status | WebDAV: status for multiple resources returned in the XML body within a single request. |
| 208 | Already Reported | WebDAV: already reported in a previous response within the same binding. |
| 226 | IM Used | HTTP delta encoding: the server applied one or more instance manipulations. |
SRE note: If you have an API using 202, always define a polling mechanism or webhook callback strategy. "Request accepted" does not mean "completed" — document this distinction for clients and track the 202 → completion time as a separate metric in monitoring.
3xx — Redirection
| Code | Name | What it means |
|---|---|---|
| 300 | Multiple Choices | Multiple options available; client must choose (e.g. different language or format). Rarely used. |
| 301 | Moved Permanently | Resource permanently moved. Browsers and search engines cache the new URL from the Location header. |
| 302 | Found | Temporary redirect. After a POST, browsers typically follow with a GET (PRG pattern). |
| 303 | See Other | Always redirect with GET after POST/PUT/DELETE. Standard behavior after form submission. |
| 304 | Not Modified | Cache is valid; no body sent. Response to conditional requests with If-None-Match / If-Modified-Since. Critical for bandwidth savings. |
| 307 | Temporary Redirect | Temporary redirect; method does not change (POST → POST). This is the key difference from 302. |
| 308 | Permanent Redirect | Permanent redirect; method does not change. Preferred over 301 for HTTPS migrations. |
SRE note: Use 308 instead of 301 for HTTP → HTTPS migrations. With 301, browsers cache the original method and may convert POST requests to GET. Kubernetes ingress with
ssl-redirect: "true" returns 308 — that's the correct behavior. Check redirect chains: curl -L -v https://domain.com 2>&1 | grep -E "< HTTP|Location" — more than two redirect hops is costly for SEO.
4xx — Client Errors
| Code | Name | What it means |
|---|---|---|
| 400 | Bad Request | Server could not understand the request. Malformed syntax, invalid parameter, or missing required field. |
| 401 | Unauthorized | Authentication required or failed. The WWW-Authenticate header indicates the expected auth scheme. |
| 402 | Payment Required | Payment required. Many SaaS APIs use this when a rate limit is exceeded. |
| 403 | Forbidden | Identity confirmed but access to this resource is not permitted. |
| 404 | Not Found | Resource not found. Either doesn't exist or intentionally hidden (as a security measure instead of 403). |
| 405 | Method Not Allowed | This HTTP method is not valid for this endpoint. The Allow header lists permitted methods. |
| 406 | Not Acceptable | Server cannot produce a response in the format specified in the Accept header. Content negotiation failed. |
| 407 | Proxy Auth Required | Like 401 but for proxy authentication. |
| 408 | Request Timeout | Client did not complete the request within the allowed time. Server closed the connection. |
| 409 | Conflict | Request conflicts with the current state of the resource. Simultaneous updates, duplicate records, or version mismatch. |
| 410 | Gone | Resource permanently deleted and will not return. Important for SEO — search engines remove the URL from their index. |
| 411 | Length Required | Content-Length header is required but was not sent. |
| 412 | Precondition Failed | If-Match / If-Unmodified-Since condition failed. Used for optimistic locking. |
| 413 | Content Too Large | Request body exceeds the server's accepted limit. File upload size limit exceeded. |
| 414 | URI Too Long | URL is longer than the server can process. Usually caused by excessively long query strings. |
| 415 | Unsupported Media Type | Content-Type is not supported by the server. Like sending XML to a JSON API. |
| 416 | Range Not Satisfiable | Range header is invalid or exceeds the resource size. |
| 417 | Expectation Failed | The condition in the Expect header cannot be met by the server. |
| 418 | I'm a Teapot | Easter egg from RFC 2324: a teapot refusing to brew coffee. |
| 421 | Misdirected Request | Request directed to a server unable to produce a response. Seen in HTTP/2 multiplexing issues. |
| 422 | Unprocessable Content | Syntax is valid but semantic errors exist. Standard for form validation errors. |
| 423 | Locked | WebDAV: resource is locked. |
| 424 | Failed Dependency | WebDAV: this request failed because another operation it depended on failed. |
| 425 | Too Early | Request sent with early data (0-RTT) rejected due to replay risk. Related to TLS 1.3. |
| 426 | Upgrade Required | Client must upgrade to the specified protocol. The Upgrade header indicates which protocol is required. |
| 428 | Precondition Required | Conditional request (If-Match) is mandatory — the resource must not be updated blindly. |
| 429 | Too Many Requests | Rate limit exceeded. The Retry-After header indicates when to try again. |
| 431 | Header Fields Too Large | Headers are too large. Large cookies or too many custom headers. |
| 451 | Unavailable For Legal Reasons | Content blocked for legal reasons. Country-based restrictions or court orders. |
SRE note: Always set the
Retry-After header for 429 and write clients that implement exponential backoff. APIs without rate limiting are exposed to cascade failure under load spikes. Wire up a Prometheus alert on http_requests_total{status="429"} — a sudden spike in 429s means either an attack or a client stuck in a loop.
5xx — Server Errors
| Code | Name | What it means |
|---|---|---|
| 500 | Internal Server Error | General server error. Catch-all: unexpected exception, null pointer, unhandled error. |
| 501 | Not Implemented | Server does not support this HTTP method. Seen in partial HTTP implementations. |
| 502 | Bad Gateway | Proxy/gateway received an invalid response from the upstream server. The most common 5xx — pod not ready or in a crash loop. |
| 503 | Service Unavailable | Server temporarily out of service. Overloaded or in maintenance mode. |
| 504 | Gateway Timeout | Proxy/gateway did not receive a timely response from upstream. Pod is responding but the ingress timeout was exceeded. |
| 505 | HTTP Version Not Supported | Server does not support the HTTP version used in the request. |
| 506 | Variant Also Negotiates | Content negotiation led to a circular reference. Misconfiguration. |
| 507 | Insufficient Storage | WebDAV: not enough storage to complete the operation. |
| 508 | Loop Detected | WebDAV: infinite loop detected. |
| 510 | Not Extended | Additional extension required to fulfill the request. |
| 511 | Network Auth Required | Authentication required to access the network. Seen on captive portals (WiFi login pages). |
Debugging 502 and 504 in Kubernetes:
502 Bad Gateway → Pod not ready, in a crash loop, or listening on the wrong port504 Gateway Timeout → Pod is responding but the ingress timeout was exceeded
502 debug steps:
# Check that pods are Running and Ready
kubectl get pods -n <namespace> -o wide
# Verify endpoints are registered
kubectl get endpoints <service-name> -n <namespace>
# Look at pod logs
kubectl logs -n <namespace> <pod-name> --previous
# Check that the service selector matches the pod labels
kubectl describe service <service-name> -n <namespace>
For 504, increase ingress timeouts:
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
nginx.ingress.kubernetes.io/proxy-send-timeout: "120"
nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
Monitoring HTTP Status Codes with Prometheus
groups:
- name: http_errors
rules:
- alert: HighErrorRate5xx
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
/
sum(rate(http_requests_total[5m])) by (service)
> 0.01
for: 2m
labels:
severity: critical
annotations:
summary: "{{ $labels.service }}: 5xx error rate > 1%"
- alert: SuddenSpike4xx
expr: |
sum(rate(http_requests_total{status=~"4.."}[5m])) by (service)
> 50
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.service }}: 4xx spike detected"
Which Code for Which Scenario — REST API Quick Reference
| Scenario | Correct Code |
|---|---|
| Successful GET request | 200 OK |
| Resource created via POST | 201 Created |
| Successful DELETE, no body | 204 No Content |
| Async job queued | 202 Accepted |
| Form validation error | 422 Unprocessable Content |
| Duplicate record (email already exists) | 409 Conflict |
| No token or invalid token | 401 Unauthorized |
| Valid token, insufficient permission | 403 Forbidden |
| Resource not found | 404 Not Found |
| Rate limit exceeded | 429 Too Many Requests |
| Unexpected server error | 500 Internal Server Error |
Tags HTTP API SRE Networking