416 Range Not Satisfiable
Применение
Когда получено сообщение об ошибке 416 Range Not Satisfiable, значит клиент запросил часть содержимого с помощью заголовка Range. Для байтовых диапазонов эта ошибка возвращается, если первый байт указанного диапазона больше длины ресурса.
Одна из причин запрашивать частичные диапазоны — передача больших файлов, когда клиент хочет скачивать файл по частям. Благодаря заголовку Range в запросе файл фактически скачивается по фрагментам и в произвольном порядке.
Когда сервер удовлетворяет запрос и возвращает хотя бы один из запрошенных диапазонов как подмножество ресурса, в знак успеха возвращается 206. Серверы вправе проигнорировать запросы диапазонов и вернуть ресурс целиком со статусом 200.
В составе ответа сервер формирует заголовок Content-Range, указывающий текущую длину данных:
Content-Range: bytes */512
Звёздочка * перед разделителем / обозначает неудовлетворимый диапазон, а за ней следует общий размер ресурса.
Влияние на SEO
Поисковые системы вроде Google не индексируют URL со статусом ответа 416. Ранее проиндексированные URL будут удалены из результатов поиска.
Пример
Клиент запрашивает байты с 1000 по 2000 некоего ресурса. Сервер возвращает 416 Range Not Satisfiable, поскольку длина файла составляет всего 512 байт. Пользуясь полученной от сервера информацией об общем размере, клиент пересоздаёт запрос с корректным диапазоном.
Запрос
GET /documents/main HTTP/1.1
Host: example.com
Range: bytes=1000-2000
Ответ
HTTP/1.1 416 Range Not Satisfiable
Content-Range: bytes */512
Альтернативный ответ, когда сервер игнорирует диапазон
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 512
<entire 512 bytes in message body>
Как исправить
Заголовок Range задаёт байтовый диапазон за пределами границ ресурса. Самая частая причина — запрос байтов за концом файла (например, запрос байтов 1000-2000 у файла длиной всего 512 байт).
Сначала проверьте размер ресурса. Отправьте запрос HEAD, чтобы прочитать заголовок Content-Length, прежде чем формировать запрос диапазона. Это предотвращает запрос байтов за границей файла.
Проверьте арифметику байтового диапазона. Байтовые диапазоны нумеруются с нуля и включают оба конца. У файла размером 512 байт допустимые позиции байтов — от 0 до 511. Диапазон bytes=0-511 запрашивает весь файл. Ошибки на единицу в расчётах диапазона — частый источник ответов 416.
Учитывайте изменения ресурса. При возобновлении загрузки файл на сервере мог измениться или быть удалён с момента последнего частичного запроса. Диапазон, корректный для предыдущей версии, становится недействительным для более короткого или другого файла. Перед возобновлением заново проверьте размер ресурса.
Уберите заголовок Range. Когда частичное содержимое не требуется, уберите заголовок Range, чтобы запросить ресурс целиком. Сервер вместо этого вернёт 200 с полным телом.
Очистите кэш браузера. Браузеры иногда кэшируют частичные ответы и при последующих визитах формируют некорректные запросы диапазонов. Очистка кэша вынуждает выполнить новый полный запрос.
Особенности на стороне сервера. Некоторые конфигурации сервера ограничивают, какие типы ресурсов поддерживают запросы диапазонов. Убедитесь, что сервер отправляет Accept-Ranges: bytes в ответах для целевого ресурса. Если присутствует Accept-Ranges: none, сервер вообще не поддерживает частичные запросы к этому ресурсу.
Сбои загрузки медиа
Видео- и аудиоплееры в браузерах отправляют запросы диапазонов для потокового воспроизведения медиафайлов. Ошибка 416 во время воспроизведения означает, что плеер запросил байтовый диапазон за границей файла. Так происходит, когда медиафайл заменили более короткой версией, а плеер удерживал устаревшее значение Content-Length. Перезагрузка страницы вынуждает плеер получить актуальный размер файла до запроса диапазонов.
Примеры кода
.NET
HttpStatusCode.RequestedRangeNotSatisfiable
Rust
http::StatusCode::RANGE_NOT_SATISFIABLE
Rails
:range_not_satisfiable
:requested_range_not_satisfiable
Go
http.StatusRequestedRangeNotSatisfiable
Symfony
Response::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE
Python3.5+
http.HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE
Java
HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE
Angular
@angular/common/http/HttpStatusCode.RangeNotSatisfiable