Código de status HTTP · Erros do cliente (4xx)
Erro 416 Range Not Satisfiable
O erro 416 Range Not Satisfiable significa que o cliente pediu, com o cabeçalho Range, um trecho do arquivo que não existe, normalmente começando depois do fim. O caso clássico é retomar um download que já estava completo, ou de um arquivo que mudou no servidor.
| Classe | 4xx, Erros do cliente |
|---|---|
| Também chamado de | Requested Range Not Satisfiable |
| Definido em | RFC 9110 §15.5.17 |
| Pode ir para o cache por padrão | Só com Cache-Control ou Expires explícitos |
| Pode repetir o pedido | Sim, com um intervalo dentro do tamanho informado em Content-Range, ou sem Range |
| Cabeçalhos relevantes |
|
O que significa o 416
A RFC 9110, seção 15.5.17, dá dois motivos: nenhum dos intervalos pedidos pode ser atendido, ou o cliente pediu intervalos pequenos ou sobrepostos demais, o que a especificação trata como possível ataque de negação de serviço. Um servidor que responde 416 a um pedido por bytes deve enviar Content-Range com asterisco e o tamanho atual, como Content-Range: bytes */47022, para o cliente descobrir o tamanho real.
O servidor também pode ignorar o Range e mandar o arquivo inteiro com 200, e muitos fazem isso. Quase nunca se escreve 416 na mão: http.ServeContent e http.ServeFile do Go, res.sendFile e express.static do Express, o nginx e o S3 geram o código sozinhos quando o intervalo sai dos limites. O S3 chama o erro de InvalidRange.
Causas comuns
Se você está visitando o site
- Um gerenciador de downloads ou o navegador tentou retomar um arquivo que já tinha terminado de baixar.
- O arquivo no servidor foi trocado por uma versão menor depois que o seu download parcial começou.
Se você administra o servidor
- O curl -C - ou o wget -c tenta retomar a partir de um arquivo local do mesmo tamanho, ou maior, que o remoto.
- Um player de vídeo busca uma posição em bytes calculada com metadados antigos, depois que o arquivo foi recodificado.
- O cliente manda um pedido com Range para um arquivo de zero bytes; nenhum intervalo pode ser atendido quando a representação está vazia.
- A CDN guardou em cache uma versão mais curta do objeto do que a origem tem agora, e intervalos perto do fim falham na borda.
Como resolver
Se você está visitando o site
- Apague o arquivo parcial e baixe de novo desde o início.
- Recarregue a página do vídeo ou arquivo para o player buscar metadados atualizados.
Se você administra o servidor
- Leia o tamanho em Content-Range: bytes */TAMANHO no 416 e compare com o arquivo parcial local; se forem iguais, o download já está completo.
- Envie If-Range com o ETag ao retomar, para o servidor devolver o arquivo novo inteiro com 200 se ele mudou, em vez de 416 ou de uma mistura corrompida.
- Limpe o objeto na CDN depois de trocar um arquivo por outro de tamanho diferente.
Como enviar um 416
Raramente é preciso escrever isso na mão. http.ServeContent e http.ServeFile do Go, res.sendFile e express.static do Express e os arquivos estáticos do nginx respondem 416 com o Content-Range certo automaticamente.
app.get('/files/:name', (req, res) => {
res.set('Content-Range', 'bytes */47022');
res.status(416).end();
});// app/files/[name]/route.ts
export async function GET() {
return new Response(
null,
{ status: 416, headers: { 'Content-Range': 'bytes */47022' } }
);
}mux.HandleFunc("GET /files/{name}", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Range", "bytes */47022")
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable) // 416
})from fastapi import FastAPI, Response
app = FastAPI()
@app.get("/files/{name}")
def get_file(name: str):
return Response(status_code=416, headers={"Content-Range": "bytes */47022"})# Ask for bytes past the end of a 47022-byte file
curl -sI -H 'Range: bytes=50000-' https://example.com/files/report.pdf
# HTTP/2 416
# content-range: bytes */47022Costuma ser confundido com
- 416 vs 206
- O 206 Partial Content é a resposta de sucesso a um pedido com Range; o 416 é a falha quando o intervalo é impossível.
- 416 vs 200
- Um servidor que ignora o Range manda 200 com o arquivo inteiro, o que também é permitido e evita o 416.
Perguntas frequentes
- Por que o curl -C - devolve 416?
- O curl pede bytes a partir do tamanho do seu arquivo local. Se ele já está completo, o início é igual ao tamanho remoto e não sobra nenhum byte, então o servidor responde 416. Normalmente o download já terminou.
- O que uma resposta 416 deve trazer?
- A RFC 9110 diz que um servidor que responde 416 a um pedido por bytes deve incluir Content-Range: bytes */TAMANHO com o tamanho atual do recurso.
- O servidor pode simplesmente ignorar o Range?
- Pode. Suporte a intervalos é opcional, e muitos servidores respondem a um intervalo impossível ou não suportado com 200 e o corpo inteiro. O cliente precisa lidar com as duas respostas.
Revisado em por Arielton Oberek.