406 Not Acceptable: cosa significa e come risolverlo
Un 406 Not Acceptable significa che il server non riesce a produrre una risposta che corrisponda a ciò che il client ha detto di accettare. La richiesta stessa va bene; è la negoziazione tra ciò che è stato chiesto e ciò che il server è in grado di offrire a fallire, di solito sul formato, la lingua, o la codifica della risposta.
Cosa significa 406 Not Acceptable
HTTP supporta la negoziazione del contenuto attraverso una famiglia di header Accept: Accept per il tipo di media della risposta, Accept-Language per la lingua, e Accept-Encoding per la compressione. Un client può inviare uno qualunque di questi per dire "dammi solo una risposta che posso usare." Secondo RFC 9110, se il server non riesce a produrre una rappresentazione che il client ha indicato di accettare, e sceglie di segnalarlo invece di inviare comunque qualcosa, risponde 406. In pratica, la maggior parte dei server ignora silenziosamente un header Accept ristretto e invia comunque la propria risposta predefinita, il che è il motivo per cui un vero 406 è meno comune dell'header stesso.
Come appare l'errore
Un browser raramente innesca un 406 durante i normali caricamenti di pagina, perché i browser inviano header Accept permissivi che corrispondono a quasi qualunque cosa un server offra. Compare molto più spesso da client API, script, e strumenti da riga di comando che impostano un header Accept rigido:
curl -i -H "Accept: application/xml" https://api.example.com/v1/status
HTTP/1.1 406 Not Acceptable
Content-Type: application/json
In quell'esempio il client ha chiesto solo XML e l'API può produrre solo JSON, quindi il server rifiuta invece di inviare un formato che il client ha esplicitamente detto di non volere.
Cosa causa un 406 Not Acceptable
- Una negoziazione del contenuto che fallisce davvero. Un header
Accept,Accept-Language, oAccept-Encodingche nomina solo formati che il server non può produrre, il più delle volte un client che richiede XML da un'API solo-JSON, o una specifica variante di lingua che il server non ha. - Un web application firewall su hosting condiviso. Questa è una causa molto comune nel mondo reale che non ha nulla a che fare con la negoziazione del contenuto: ModSecurity e regole WAF simili su ambienti di hosting condiviso bloccano richieste il cui header Accept appare insolito, mancante, o automatizzato, e rispondono 406 come risposta di blocco indipendentemente da cosa si stesse negoziando.
- Un'API che serve solo JSON, colpita da un client che invia
Accept: text/html. Alcune API sono rigide su questo e rifiutano invece di degradare, il che si manifesta come 406 per qualunque client, incluso un tab del browser aperto direttamente sull'endpoint. - Una regola di reverse proxy o CDN mal configurata che ispeziona e rifiuta in base all'header Accept per motivi di caching o filtraggio bot, non correlati a ciò che il server di origine può produrre.
- Gestione eccessivamente rigida di Accept-Encoding. Un server configurato per rifiutare qualunque richiesta che non elenchi un metodo di compressione che preferisce, invece di ripiegare su una risposta non compressa.
Come capire di chi è la colpa
Se uno script o un'integrazione specifica è l'unica cosa che incontra 406, controlla cosa dicono i suoi header Accept, dato che un header ristretto o mal configurato lato client è spesso la causa diretta. Se la stessa richiesta funziona con un header Accept semplice e permissivo ma fallisce con uno specifico, il server davvero non riesce a servire quel formato. Se anche il normale traffico da browser è colpito, o l'errore è iniziato subito dopo un cambio di hosting o WAF senza alcun cambio di codice dal tuo lato, le regole di sicurezza dell'hosting condiviso sono il colpevole più probabile, ed eseguire un controllo HTTP da più postazioni con gli header esatti che la tua integrazione invia è il modo più veloce per confermare se il blocco è coerente o specifico a una rete.
Come correggere un 406 Not Acceptable
Se sei un visitatore
- Rimuovi o allenta l'header Accept in qualunque script o strumento stia facendo la richiesta, se lo controlli tu, e lascia che accetti il formato predefinito che il server offre.
- Controlla la documentazione dell'API per quali tipi di contenuto e lingue supporta prima di assumere che il server sia rotto.
- Prova la richiesta da un browser direttamente, dato che i browser inviano header Accept ampi e raramente incontrano questo errore, il che aiuta a confermare che il blocco sia specifico agli header del tuo client.
Se gestisci il sito
- Controlla prima le tue regole ModSecurity o WAF se il 406 è inaspettato e diffuso, dato che gli ambienti di hosting condiviso bloccano frequentemente in base a pattern dell'header Accept piuttosto che a un vero fallimento di negoziazione. Guarda i log stessi del WAF per l'id della regola corrispondente prima di toccare il codice applicativo.
- Conferma quali formati la tua API effettivamente serve, e o supporta di più ciò che i client reali chiedono o documenta chiaramente il requisito così che un 406 sia informativo invece che sorprendente.
- Ripiega su una rappresentazione predefinita invece di rifiutare del tutto, dove ciò è accettabile per la tua API, dato che la maggior parte dei client nel mondo reale gestisce meglio "ecco JSON anche se hai chiesto genericamente" rispetto a un rifiuto netto.
- Controlla le regole di reverse proxy e CDN per qualunque cosa ispezioni l'header Accept per il caching o la gestione dei bot, dato che una regola pensata per uno scopo può produrre 406 come effetto collaterale per traffico non correlato.
Come prevenire che un 406 abbatta un'integrazione
Un 406 introdotto da un aggiornamento di sicurezza del provider di hosting o una nuova regola WAF non apparirà come un'interruzione dall'interno della tua stessa rete, dato che le tue stesse richieste potrebbero usare header diversi da quelli di un'integrazione colpita. Un controllo HTTP pianificato che invia lo stesso header Accept che i tuoi client reali usano, con un'asserzione sul codice di stato atteso, coglie un fallimento di negoziazione nel momento in cui inizia. Controllare da più postazioni aiuta anche a distinguere una regola WAF a livello di tutto l'hosting da una che si applica solo su certi nodi edge.
Errori correlati
Vedi 403 Forbidden per il caso strettamente correlato di una regola WAF o bot che blocca una richiesta del tutto invece che tramite negoziazione del contenuto, la panoramica 4xx per la famiglia più ampia, e 413 Payload Too Large altrove in questo lotto.
Domande frequenti
Il 406 è la stessa cosa di un errore CORS?
No. I fallimenti CORS avvengono perché il browser si rifiuta di esporre una risposta cross-origin allo script chiamante; il 406 è il server stesso che rifiuta di produrre affatto un corpo di risposta perché non riesce a soddisfare il formato, la lingua, o la codifica richiesti.
Perché vedo il 406 solo da curl o Postman, mai dal browser?
I browser inviano header Accept ampi e permissivi per impostazione predefinita. Strumenti come curl non inviano nulla o inviano un header ristretto a meno che tu non ne imposti uno esplicitamente, il che è molto più probabile che inneschi un vero fallimento di negoziazione o faccia scattare una regola WAF calibrata per segnalare header insoliti.
Un 406 può arrivare da ModSecurity anche se il mio header Accept è completamente normale?
Sì. Molti set di regole ModSecurity su hosting condiviso segnalano le richieste come automatizzate in base a una combinazione di segnali, inclusa la struttura e l'ordine esatti degli header Accept, e rispondono 406 come risposta di blocco generica piuttosto che perché la negoziazione del contenuto sia effettivamente fallita.
La mia API dovrebbe restituire 406 o semplicemente ripiegare su JSON?
Ripiegare su un formato sensato è più amichevole per i client nel mondo reale ed è ciò che fa la maggior parte delle API in produzione. Restituire 406 è difendibile quando servire silenziosamente il formato sbagliato sarebbe attivamente fuorviante per chi chiama.
Qual è la differenza tra 406 e 415?
406 riguarda ciò che il client può accettare nella risposta. 415 Unsupported Media Type riguarda ciò che il server può accettare nel corpo della richiesta che il client ha inviato. Coprono direzioni opposte della stessa idea di negoziazione.