406 Not Acceptable
Uso
Cuando llega un error 406 Not Acceptable, la respuesta la desencadena una cabecera relacionada con la negociación, como Accept o Accept-Language. Cuando el cliente incluye una o varias de estas cabeceras, el servidor satisface esos requisitos siempre que le sea posible.
Las cabeceras HTTP Accept más habituales son:
Accept: especifica el tipo de contenido preferido. El servidor puede proporcionar una representación en texto plano o en HTML. En este ejemplo, el cliente prefiere HTML, pero también acepta texto plano.
Accept: text/html, text/plain
Accept-Encoding: especifica las codificaciones que acepta el cliente. En este ejemplo, el cliente indica que admite la compresión gzip.
Accept-Encoding: gzip
En la práctica, este error se usa muy poco, porque el servidor suele entregar una representación predeterminada en su lugar. El razonamiento parte de que el cliente prefiere algo antes que nada. Cuando sí se devuelve una respuesta 406 Not Acceptable, el cuerpo del mensaje contiene una lista de representaciones disponibles entre las que el cliente puede elegir.
Nota
406 Not Acceptable significa que el servidor no puede producir una respuesta que coincida con las cabeceras Accept del cliente (problema de formato de salida). 415 Unsupported Media Type significa que el servidor no entiende el Content-Type del cuerpo de la solicitud (problema de formato de entrada). El 406 tiene que ver con lo que el cliente quiere recibir, mientras que el 415 tiene que ver con lo que el cliente envió.
Impacto en SEO
Los motores de búsqueda como Google no indexan una URL que devuelve el estado 406 Not Acceptable. Las URL indexadas previamente que pasan a devolver este código de estado se eliminan de los resultados de búsqueda.
Ejemplo
El cliente solicita un recurso en francés, pero el servidor responde con 406 Not Acceptable porque solo hay versiones disponibles en alemán e inglés.
Solicitud
GET /news HTTP/1.1
Host: example.com
Accept-Language: fr
Respuesta
HTTP/1.1 406 Not Acceptable
Content-Type: text/html
Content-Length: 242
<html>
<head>
<title>French Language Not Available</title>
</head>
<body>
<p>Please choose a supported language:</p>
<p><a href="/news/news-de.html">German</a></p>
<p><a href="/news/news-en.html">English</a></p>
</body>
</html>
Cómo solucionarlo
Un 406 Not Acceptable significa que el servidor no tiene ninguna representación que coincida con las cabeceras de negociación de contenido del cliente.
Revise la cabecera Accept. Amplíe los tipos de medios aceptados. Por ejemplo, añada application/json junto a text/html, o use / para aceptar cualquier formato. Utilice las herramientas de desarrollo del navegador (pestaña Network) o curl -v para inspeccionar la cabecera Accept exacta que envía el cliente.
Compruebe las restricciones de Accept-Language. Solicitar un idioma que el servidor no admite desencadena este error. Amplíe la lista de idiomas o añada un comodín (*) como alternativa. La configuración de idioma del navegador controla esta cabecera de forma automática. Ajústela en las preferencias de idioma del navegador.
Elimine valores de Accept-Encoding o Accept-Charset excesivamente restrictivos. Un requisito de codificación o de juego de caracteres demasiado estrecho limita las opciones del servidor. Permita valores habituales como gzip, deflate y UTF-8.
Inspeccione el cuerpo de la respuesta en busca de alternativas disponibles. El servidor suele enumerar las representaciones admitidas en la respuesta 406. Seleccione una y ajuste las cabeceras de negociación en consecuencia.
Revise la configuración de negociación de contenido del lado del servidor. Unos mapas de tipos mal configurados o la falta de registros de tipos MIME en el servidor provocan respuestas 406 inesperadas. En Apache, mod_negotiation y MultiViews controlan los mapas de tipos. Verifique que las directivas AddType registran los tipos MIME necesarios.
Revise las reglas de mod_security o del WAF. El mod_security de Apache (y WAF similares) intercepta solicitudes y devuelve 406 cuando una regla se activa por el contenido de la solicitud, no por la cabecera Accept. Consulte el registro de errores del servidor en busca de una entrada de ModSecurity y anote el ID de la regla (por ejemplo, [id “941160”]). Añada esa regla concreta a la lista de permitidos en lugar de desactivar el WAF por completo:
SecRuleRemoveById 941160
Coloque la exclusión en la configuración del host virtual o en el archivo .htaccess.
Pruebe con una solicitud mínima. Elimine todas las cabeceras de negociación y envíe una solicitud desnuda con curl para determinar si el servidor devuelve una representación predeterminada. Si la solicitud desnuda funciona, vuelva a añadir las cabeceras de negociación de una en una para aislar cuál provoca el rechazo.
Verifique la negociación de versiones de la API. Algunas API usan la cabecera Accept para el versionado (por ejemplo, application/vnd.api.v2+json). Enviar una cadena de versión no admitida produce un 406. Confirme el valor de versión en la documentación de la API.
Referencias de código
.NET
HttpStatusCode.NotAcceptable
Rust
http::StatusCode::NOT_ACCEPTABLE
Rails
:not_acceptable
Go
http.StatusNotAcceptable
Symfony
Response::HTTP_NOT_ACCEPTABLE
Python3.5+
http.HTTPStatus.NOT_ACCEPTABLE
Java
java.net.HttpURLConnection.HTTP_NOT_ACCEPTABLE
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_NOT_ACCEPTABLE
Angular
@angular/common/http/HttpStatusCode.NotAcceptable