Какие HTTP статус коды вы знаете
Первая цифра определяет класс ответа:
🟢 Junior Level
HTTP статус-код (Status Code) — это трехзначное числовое значение, которое сервер отправляет в стартовой строке ответа клиенту для сообщения о результате обработки запроса.
Первая цифра определяет класс ответа:
| Класс | Категория | Значение |
|---|---|---|
1xx |
Информационные (Informational) | Запрос получен, обработка продолжается (напр. 100 Continue). |
2xx |
Успех (Success) | Действие успешно принято, понято и обработано. |
3xx |
Перенаправление (Redirection) | Для завершения запроса требуются дальнейшие действия клиента. |
4xx |
Ошибка клиента (Client Error) | Запрос содержит синтаксическую ошибку или не может быть выполнен по вине клиента. |
5xx |
Ошибка сервера (Server Error) | Сервер столкнулся с непредвиденной ошибкой при обработке корректного запроса. |
Базовые статус-коды, которые обязан знать каждый разработчик
200 OK: Стандартный ответ при успешном выполнении запроса (обычно с телом ответа).201 Created: Ресурс успешно создан (например, в ответ наPOST). Сервер обычно возвращает заголовокLocationс URI нового ресурса.204 No Content: Запрос выполнен успешно, но тело ответа намеренно отсутствует (типично дляDELETEилиPUT).301 Moved Permanently: Ресурс навсегда перемещен на новый URL.302 Found: Временное перенаправление на другой URL.400 Bad Request: Некорректный синтаксис запроса (битый JSON, недопустимый формат данных).401 Unauthorized: Пользователь не аутентифицирован (сервер не знает, кто обращается; требуется заголовокAuthorization).403 Forbidden: Пользователь аутентифицирован, но у него нет прав доступа к ресурсу.404 Not Found: Запрошенный ресурс не найден на сервере.500 Internal Server Error: Непредвиденное исключение или сбой в коде приложения на стороне сервера.503 Service Unavailable: Сервер временно не может обработать запрос (перегрузка, техническое обслуживание).
🟡 Middle Level
Разделение кодов и протокольные тонкости (RFC 9110)
1. Успешные ответы (2xx)
202 Accepted: Запрос принят на обработку, но она еще не завершена. Применяется в асинхронных архитектурах (очереди, фоновые задачи). Клиент получает идентификатор задачи для последующей проверки статуса.206 Partial Content: Сервер возвращает только часть содержимого ресурса (используется при докачке файлов и видео-стриминге по заголовкуRange).
2. Перенаправления (3xx): Революция 307 и 308
Исторически браузеры ошибочно трансформировали метод POST в GET при получении редиректов 301 и 302.
Для устранения этой проблемы в спецификацию были введены строгие коды:
303 See Other: Прямо предписывает клиенту сделатьGETна новый URL (основа паттерна Post/Redirect/Get).307 Temporary Redirect: Временное перенаправление, строго сохраняющее исходный HTTP-метод и тело (POST остается POST).308 Permanent Redirect: Постоянное перенаправление, строго сохраняющее HTTP-метод и тело.304 Not Modified: Ответ на условный запрос (If-None-MatchилиIf-Modified-Since). Тело ответа отсутствует, клиент берет данные из локального кэша (экономия трафика и времени).
3. Ошибки клиента (4xx)
401 vs 403:401 Unauthorizedобязан содержать заголовокWWW-Authenticate. Означает: «Вы не подтвердили свою личность».403 Forbidden: личность подтверждена, но RBAC/ABAC доступ закрыт. Повтор запроса с теми же учетными данными бесполезен.
400 vs 422:400 Bad Request: сервер не смог распарсить запрос (синтаксический сбой, невалидный JSON, некорректная кодировка).422 Unprocessable Content(ранее Entity): синтаксис JSON корректен, но нарушены бизнес-правила или Bean Validation (например, отрицательный возраст или невалидный email).
409 Conflict: Конфликт состояния данных (попытка регистрации уже существующего email, конфликт уникального индекса).410 Gone: Ресурс был на сервере, но намеренно и навсегда удален без предоставления адреса перенаправления.412 Precondition Failed: Не прошла проверка условного заголовка (If-Matchпри оптимистической блокировке).415 Unsupported Media Type: Сервер не поддерживает формат данных, переданный вContent-Type(например, прислан XML вместо JSON).429 Too Many Requests: Сработал Rate Limiter. Сервер обязан передать заголовокRetry-After: <seconds>.
4. Ошибки сервера (5xx)
502 Bad Gateway: Прокси-сервер (NGINX / Envoy / Cloudflare) получил некорректный ответ или сброс TCP-соединения от бэкенда (Java-приложения).503 Service Unavailable: Бэкенд временно недоступен (перегрузка пула потоков Tomcat, сервис на обслуживании).504 Gateway Timeout: Бэкенд не ответил прокси-серверу за отведенное время (таймаутproxy_read_timeout).
🔴 Senior Level
Стандартизация ошибок: RFC 9457 (Problem Details for HTTP APIs)
Возврат произвольных JSON-структур при ошибках ({"error": "bad request", "code": 12}) признан анти-паттерном.
Современным стандартом индустрии является RFC 9457 (заменивший RFC 7807), нативно встроенный в Spring Boot 3+ через класс ProblemDetail (Content-Type: application/problem+json).
{
"type": "https://api.example.com/errors/insufficient-funds",
"title": "Insufficient Funds",
"status": 422,
"detail": "Your balance of 1500 USD is insufficient for debiting 2000 USD",
"instance": "/api/v1/accounts/101/debit",
"timestamp": "2026-09-26T08:30:00Z",
"traceId": "9b1deb4d3b7d4bad9bdd2b0d7b3dcb6d"
}
Production-ready обработчик ошибок на Spring Boot 3
package com.example.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.net.URI;
import java.time.Instant;
import java.util.Map;
import java.util.stream.Collectors;
@RestControllerAdvice
public class GlobalExceptionHandler {
// 1. Ошибки валидации DTO -> 422 Unprocessable Content
@ExceptionHandler(MethodArgumentNotValidException.class)
public ProblemDetail handleValidationException(MethodArgumentNotValidException ex) {
ProblemDetail problem = ProblemDetail.forStatusAndDetail(
HttpStatus.UNPROCESSABLE_ENTITY,
"Validation failed for one or more fields"
);
problem.setTitle("Unprocessable Content");
problem.setType(URI.create("https://api.example.com/errors/validation"));
problem.setProperty("timestamp", Instant.now());
Map<String, String> invalidFields = ex.getBindingResult().getFieldErrors().stream()
.collect(Collectors.toMap(
FieldError::getField,
fe -> fe.getDefaultMessage() != null ? fe.getDefaultMessage() : "Invalid value",
(existing, replacement) -> existing
));
problem.setProperty("invalidFields", invalidFields);
return problem;
}
// 2. Бизнес-конфликт -> 409 Conflict
@ExceptionHandler(UserAlreadyExistsException.class)
public ProblemDetail handleUserExistsException(UserAlreadyExistsException ex) {
ProblemDetail problem = ProblemDetail.forStatusAndDetail(
HttpStatus.CONFLICT,
ex.getMessage()
);
problem.setTitle("Resource Conflict");
problem.setType(URI.create("https://api.example.com/errors/user-conflict"));
problem.setProperty("timestamp", Instant.now());
return problem;
}
// 3. Непредвиденные ошибки -> 500 Internal Server Error (без утечки stack trace!)
@ExceptionHandler(Exception.class)
public ProblemDetail handleGenericException(Exception ex) {
ProblemDetail problem = ProblemDetail.forStatusAndDetail(
HttpStatus.INTERNAL_SERVER_ERROR,
"An unexpected internal error occurred. Please contact support."
);
problem.setTitle("Internal Server Error");
problem.setType(URI.create("https://api.example.com/errors/internal"));
problem.setProperty("timestamp", Instant.now());
return problem;
}
}
Highload, Observability и влияние кодов на инфраструктуру
- Negative Caching в CDN / Edge:
- Ответы
404 Not Foundмогут кэшироваться в CDN (Cloudflare) на короткое время (например, 10 секунд), чтобы защитить бэкенд от сканирования ботами и DDoS.
- Ответы
- Circuit Breaker (Resilience4j / Envoy):
- Circuit Breaker настраивается на процент ответов
5xx(включая502,503,504). Ошибки4xxклассифицируются как штатные ошибки клиентов и не должны приводить к размыканию цепи.
- Circuit Breaker настраивается на процент ответов
- Observability (SRE Golden Signals):
- Метрики
http_server_requests_seconds_count{status=~"5.."}запускают PagerDuty алерты, так как500означает дефект в коде бэкенда, тогда как всплеск429указывает на необходимость пересмотра квот Rate Limiter.
- Метрики
🎯 Шпаргалка для интервью
30-секундный ответ
HTTP статус-коды делятся на 5 классов:
- 1xx: Информационные (
100 Continue).- 2xx: Успех:
200 OK,201 Created(сLocation),202 Accepted(асинхронные задачи),204 No Content(успех без тела).- 3xx: Редиректы:
301/302(исторические),303 See Other(PRG-паттерн),304 Not Modified(кэш),307/308(строго сохраняют метод и тело).- 4xx: Ошибки клиента:
400(синтаксис),401(нет аутентификации, нуженWWW-Authenticate),403(нет прав),404(не найдено),409(конфликт данных),412(конфликт ETag),422(ошибки валидации),429(Rate limit сRetry-After).- 5xx: Ошибки сервера:
500(баг кода),502(упал бэкенд за NGINX),503(перегрузка сервиса),504(таймаут ответа бэкенда).В современном REST API ошибки стандартизируются по RFC 9457 Problem Details.
4 каверзных вопроса с ответами
-
В чем разница между статус-кодами 302 Found и 307 Temporary Redirect? Ответ: Исторически браузеры при получении кода
302 Foundтрансформировали методPOSTвGET. Код307 Temporary Redirectстрого специфицирован в RFC 9110: клиент обязан повторить перенаправленный запрос с тем же самым HTTP-методом и телом, что критично для безопасности мутирующих операций в REST API. -
Когда следует возвращать 400 Bad Request, а когда 422 Unprocessable Content? Ответ:
400 Bad Requestвозвращается при синтаксических ошибках, когда сервер в принципе не смог распарсить запрос (битый JSON, недопустимый заголовок).422 Unprocessable Contentвозвращается, когда синтаксис корректен, но нарушена семантика данных (ошибки валидации полей, пустые обязательные параметры). -
Почему код 500 не должен использоваться для бизнес-ошибок (например, недостаточно денег на счете)? Ответ: Статусы
5xxсигнализируют о сбое инфраструктуры или необработанном исключении в коде (баге). Инфраструктурные мониторинги (SRE, Prometheus, Circuit Breaker) реагируют на5xxразмыканием цепи и вызовом дежурных инженеров. Для ожидаемых отказов бизнес-логики необходимо возвращать4xx(409 Conflict,422 Unprocessable Content). -
Что обязательно должен содержать ответ сервера со статусом 401 Unauthorized по стандарту HTTP? Ответ: По спецификации RFC 9110 (раздел 15.5.2) ответ с кодом
401 Unauthorizedобязан содержать заголовок ответаWWW-Authenticate, указывающий хотя бы одну поддерживаемую схему аутентификации (например,WWW-Authenticate: Bearer realm="api").
Красные флаги (чего категорически нельзя говорить)
- ❌ «401 и 403 — это синонимы» (401 — неизвестна личность пользователя, 403 — личность известна, но доступ запрещен политикой прав).
- ❌ «Если в БД нет записи по ID, контроллер должен падать с 500 ошибкой» (отсутствие данных по ID клиента — это штатная ситуация
404 Not Found). - ❌ «Для бизнес-ошибок всегда возвращаем 200 OK, а статус пишем внутри JSON» (антипаттерн SOAP/RPC, ломающий HTTP-кэширование, балансировку и метрики).
- ❌ «Код 204 No Content возвращает пустую JSON-строку “{}”» (код 204 гарантирует физическое отсутствие тела ответа, размер
Content-Length: 0).