Saltar al contenido principal

Guías / Códigos de estado HTTP explicados

406 Not Acceptable: qué significa y cómo solucionarlo

Un 406 Not Acceptable significa que el servidor no puede producir una respuesta que coincida con lo que el cliente dijo que aceptaría. La propia petición está bien; la negociación entre lo que se pidió y lo que el servidor puede ofrecer falló, normalmente sobre el formato, el idioma, o la codificación de la respuesta.

Qué significa 406 Not Acceptable

HTTP admite la negociación de contenido mediante una familia de cabeceras Accept: Accept para el tipo de medio de la respuesta, Accept-Language para el idioma, y Accept-Encoding para la compresión. Un cliente puede enviar cualquiera de estas para decir "dame solo una respuesta que pueda usar". Según el RFC 9110, si el servidor no puede producir una representación que el cliente indicó que aceptaría, y opta por señalarlo en lugar de enviar algo de todos modos, responde 406. En la práctica, la mayoría de los servidores ignoran en silencio una cabecera Accept estrecha y envían su respuesta por defecto en su lugar, por lo que un 406 genuino es menos habitual que la propia cabecera.

Cómo aparece el error

Un navegador rara vez dispara un 406 durante la carga normal de páginas, porque los navegadores envían cabeceras Accept permisivas que coinciden con casi cualquier cosa que ofrezca un servidor. Aparece con mucha más frecuencia en clientes de API, scripts, y herramientas de línea de comandos que fijan una cabecera Accept estricta:

curl -i -H "Accept: application/xml" https://api.example.com/v1/status
HTTP/1.1 406 Not Acceptable
Content-Type: application/json

En ese ejemplo el cliente pidió solo XML y la API solo puede producir JSON, así que el servidor se niega en lugar de enviar un formato que el cliente dijo explícitamente que no quería.

Qué causa un 406 Not Acceptable

  • La negociación de contenido falla de verdad. Una cabecera Accept, Accept-Language, o Accept-Encoding que solo nombra formatos que el servidor no puede producir, casi siempre un cliente pidiendo XML a una API solo-JSON, o una variante de idioma concreta que el servidor no tiene.
  • Un firewall de aplicaciones web en hosting compartido. Esta es una causa muy habitual en el mundo real que no tiene nada que ver con la negociación de contenido: ModSecurity y reglas de WAF similares en entornos de hosting compartido bloquean peticiones cuya cabecera Accept parece inusual, ausente, o automatizada, y responden 406 como respuesta de bloqueo con independencia de qué se estuviera negociando.
  • Una API que solo sirve JSON, a la que un cliente envía Accept: text/html. Algunas API son estrictas al respecto y se niegan en lugar de degradar, lo que se manifiesta como 406 para cualquier cliente, incluida una pestaña de navegador abierta directamente en el endpoint.
  • Una regla mal configurada de un proxy inverso o de un CDN que inspecciona y rechaza según la cabecera Accept por motivos de caché o de filtrado de bots, sin relación con lo que el servidor de origen puede producir.
  • Una gestión demasiado estricta de Accept-Encoding. Un servidor configurado para rechazar cualquier petición que no liste un método de compresión que prefiere, en lugar de caer de vuelta a una respuesta sin comprimir.

Cómo saber de quién es la culpa

Si es un script o una integración concreta el único que se topa con el 406, revisa qué dicen sus cabeceras Accept, ya que una cabecera estrechada o mal configurada del lado del cliente suele ser la causa directa. Si la misma petición funciona con una cabecera Accept sencilla y permisiva pero falla con una concreta, el servidor genuinamente no puede servir ese formato. Si el tráfico normal de navegador también se ve afectado, o el error empezó justo después de un cambio de hosting o de WAF sin ningún cambio de código de tu lado, las reglas de seguridad del hosting compartido son la culpable más probable, y ejecutar una comprobación HTTP desde varias ubicaciones con las cabeceras exactas que envía tu integración es la forma más rápida de confirmar si el bloqueo es constante o específico de una red.

Cómo corregir un 406 Not Acceptable

Si eres el visitante

  1. Elimina o relaja la cabecera Accept en el script o la herramienta que hace la petición, si lo controlas, y deja que acepte el formato por defecto que ofrece el servidor.
  2. Revisa la documentación de la API para ver qué tipos de contenido e idiomas admite antes de asumir que el servidor está roto.
  3. Prueba la petición directamente desde un navegador, ya que los navegadores envían cabeceras Accept amplias y rara vez se topan con este error, lo que ayuda a confirmar que el bloqueo es específico de las cabeceras de tu cliente.

Si administras el sitio

  1. Revisa primero tus reglas de ModSecurity o de WAF si el 406 es inesperado y generalizado, ya que los entornos de hosting compartido bloquean con frecuencia por patrones de cabecera Accept en lugar de por un fallo genuino de negociación. Mira los propios registros del WAF por el id de la regla que coincidió antes de tocar el código de la aplicación.
  2. Confirma qué formatos realmente sirve tu API, y admite más de lo que piden los clientes reales o documenta el requisito con claridad para que un 406 sea informativo en lugar de una sorpresa.
  3. Cae de vuelta a una representación por defecto en lugar de rechazar directamente, donde eso sea aceptable para tu API, ya que la mayoría de los clientes reales gestionan mejor "aquí tienes JSON aunque pediste de forma amplia" que un rechazo directo.
  4. Revisa las reglas del proxy inverso y del CDN por si algo inspecciona la cabecera Accept por motivos de caché o de gestión de bots, ya que una regla pensada para un propósito puede producir un 406 como efecto secundario en tráfico sin relación.

Cómo prevenir que un 406 tumbe una integración

Un 406 introducido por una actualización de seguridad de un proveedor de hosting o por una regla de WAF nueva no se va a parecer a una caída desde dentro de tu propia red, ya que tus propias peticiones pueden usar cabeceras distintas de las de una integración afectada. Una comprobación HTTP programada que envía la misma cabecera Accept que usan tus clientes reales, con una aserción sobre el código de estado esperado, detecta un fallo de negociación en el momento en que empieza. Comprobar desde varias ubicaciones también ayuda a separar una regla de WAF de todo el hosting de una que solo se aplica en ciertos nodos de borde.

Errores relacionados

Consulta 403 Forbidden para el caso estrechamente relacionado de una regla de WAF o de bots que bloquea una petición directamente en lugar de por negociación de contenido, la guía de la familia 4xx para la familia más amplia, y 413 Payload Too Large en otro sitio de esta tanda.

Preguntas frecuentes

¿Es el 406 lo mismo que un error de CORS?

No. Los fallos de CORS ocurren porque el navegador se niega a exponer una respuesta de origen cruzado al script que la llamó; el 406 es el propio servidor negándose a producir ningún cuerpo de respuesta porque no puede satisfacer el formato, idioma, o codificación solicitados.

¿Por qué solo veo el 406 desde curl o Postman, nunca desde el navegador?

Los navegadores envían cabeceras Accept amplias y permisivas por defecto. Herramientas como curl no envían nada o envían una cabecera estrecha a menos que fijes una explícitamente, lo que tiene muchas más probabilidades de disparar un fallo genuino de negociación o de activar una regla de WAF ajustada para marcar cabeceras inusuales.

¿Puede venir un 406 de ModSecurity aunque mi cabecera Accept sea completamente normal?

Sí. Muchos conjuntos de reglas de ModSecurity de hosting compartido marcan peticiones como automatizadas basándose en una combinación de señales, incluida la estructura y el orden exactos de las cabeceras Accept, y responden 406 como respuesta de bloqueo genérica y no porque la negociación de contenido realmente fallara.

¿Debería mi API devolver 406 o simplemente caer de vuelta a JSON por defecto?

Caer de vuelta a un formato razonable es más amigable para los clientes reales y es lo que hacen la mayoría de las API en producción. Devolver 406 es defendible cuando servir el formato equivocado en silencio sería activamente engañoso para quien llama.

¿Cuál es la diferencia entre 406 y 415?

El 406 trata de lo que el cliente puede aceptar en la respuesta. El 415 Unsupported Media Type trata de lo que el servidor puede aceptar en el cuerpo de la petición que envió el cliente. Cubren direcciones opuestas de la misma idea de negociación.

Compruébalo ahora

Ejecuta la comprobación gratuita en tu propio sitio, sin necesidad de cuenta.

HTTP check

Monitoriza esto de forma permanente

Recibe un aviso en cuanto algo falle: HostTracker comprueba desde más de 300 ubicaciones y te avisa por correo, SMS, Slack, Telegram y más.

Funciones de HostTracker

Más en esta sección: Códigos de estado HTTP explicados