Códigos de estado HTTP: lista completa con significados y ejemplos
Todos los códigos de estado HTTP oficiales del 100 al 511, más los de nginx, Cloudflare y AWS, con cuándo usar cada uno.
1xx Informativos
100Continue
Respuesta provisional: el servidor ha recibido las cabeceras de la solicitud y el cliente puede seguir y enviar el cuerpo.
Los servidores la envían automáticamente cuando un cliente incluye "Expect: 100-continue" antes de subir un cuerpo grande, para que el cliente no malgaste ancho de banda en una solicitud que se rechazaría.
No la envíes desde el código de la aplicación como estado final; nunca es la respuesta a una solicitud, solo un paso previo a la respuesta real.
No aplicable
PUT /upload HTTP/1.1 Content-Length: 104857600 Expect: 100-continue HTTP/1.1 100 Continue
101Switching Protocols
El servidor acepta cambiar la conexión al protocolo indicado en la cabecera Upgrade.
La respuesta del handshake de las conexiones WebSocket (Upgrade: websocket) y, históricamente, de las actualizaciones de HTTP/1.1 a h2c.
HTTP/2 y HTTP/3 no lo usan; los WebSockets sobre HTTP/2 usan en su lugar el método CONNECT extendido (RFC 8441).
No aplicable
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
102ProcessingObsoleto
Respuesta provisional que indica al cliente que el servidor sigue trabajando en una solicitud WebDAV larga, para que no agote el tiempo de espera.
WebDAV. Eliminado de WebDAV en RFC 4918, pero sigue en el registro de IANA.
Solo en servidores WebDAV antiguos que gestionan operaciones recursivas lentas, como un COPY o MOVE profundo.
Las API nuevas deberían devolver 202 Accepted con una URL de estado para los trabajos largos.
No aplicable
HTTP/1.1 102 Processing
103Early Hints
Respuesta provisional con cabeceras Link para que el navegador empiece a precargar o preconectar mientras el servidor aún prepara la respuesta final.
Cuando el HTML tarda en generarse (renderizado en el servidor, consultas a la base de datos) y sabes qué CSS, fuentes u orígenes necesita la página. Los navegadores Chromium y Firefox actúan sobre las indicaciones preload y preconnect de las respuestas 103; Safari actúa sobre preconnect.
No pongas en ella cabeceras que solo deban aplicarse a la respuesta final, como Set-Cookie; los navegadores ignoran la mayoría de las cabeceras de una 103.
No aplicable
HTTP/1.1 103 Early Hints Link: </style.css>; rel=preload; as=style Link: <https://cdn.example.com>; rel=preconnect HTTP/1.1 200 OK Content-Type: text/html
104Upload Resumption Supported
Respuesta provisional que indica al cliente que la subida que ha iniciado se puede reanudar más tarde, y dónde.
Registro temporal de IANA para el borrador del IETF de subidas reanudables; aún no es un RFC definitivo.
Experimental: los servidores que implementan el borrador de subidas reanudables la envían con una cabecera Location para el recurso de subida.
No es para uso general hasta que el borrador se publique como RFC; la mayoría de los clientes y proxies no lo conocen.
No aplicable
draft-ietf-httpbis-resumable-upload
HTTP/1.1 104 Upload Resumption Supported Upload-Draft-Interop-Version: 6 Location: https://example.com/upload/b530ce8ff
2xx Éxito
200OKAlmacenable en caché por defecto
La solicitud se completó correctamente. El contenido del cuerpo depende del método: el recurso en GET, el resultado de la acción en POST.
La respuesta de éxito normal para GET, y para POST, PUT, PATCH o DELETE cuando devuelves un cuerpo que describe el resultado.
No devuelvas 200 con un mensaje de error en el cuerpo ("errores suaves"). Los clientes, la monitorización, las cachés y los buscadores leen el código de estado, no tu JSON.
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 200 OK
Content-Type: application/json
{"id": 42, "name": "Ada"}201Created
La solicitud se completó correctamente y creó uno o varios recursos nuevos.
Tras un POST (o un PUT a una URL nueva) que crea algo. Incluye una cabecera Location que apunte al nuevo recurso; el cuerpo suele describirlo.
No lo uses cuando no se ha creado nada nuevo, por ejemplo al actualizar un registro existente (usa 200 o 204).
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 201 Created
Location: /users/42
Content-Type: application/json
{"id": 42}202Accepted
La solicitud se aceptó para su procesamiento, pero este no ha terminado y aún puede fallar.
Trabajo en cola o asíncrono: codificación de vídeo, generación de informes, importaciones masivas. Devuelve un enlace donde el cliente pueda consultar el estado del trabajo.
No lo uses para indicar "éxito" en trabajo síncrono; explícitamente no promete nada sobre el resultado.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 202 Accepted
Location: /jobs/7f3a
Content-Type: application/json
{"status": "queued"}203Non-Authoritative InformationAlmacenable en caché por defecto
Éxito, pero un proxy transformador ha modificado la respuesta 200 del servidor de origen.
Solo lo usan intermediarios que cambian el contenido, como un proxy que comprime imágenes o reescribe HTML, para indicar al cliente que no es la respuesta exacta del origen.
Los servidores de origen y las API no deberían enviarlo.
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 203 Non-Authoritative Information Content-Type: image/webp
204No ContentAlmacenable en caché por defecto
Éxito, y no hay cuerpo de forma intencionada.
Un DELETE correcto, un PUT o PATCH cuando no devuelves el recurso actualizado, un guardado automático de formulario o la respuesta a un preflight de CORS.
Nunca incluyas un cuerpo; los clientes no lo leerán y, en HTTP/1.1, un cuerpo sobrante corrompe la siguiente respuesta de la conexión. Usa 200 si tienes algo que devolver.
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 204 No Content
205Reset Content
Éxito; el cliente debería restablecer la vista del documento, por ejemplo vaciar el formulario enviado.
Interfaces de introducción de datos en las que el usuario envía un formulario e inmediatamente introduce otro registro.
Los navegadores no implementan el restablecimiento, así que en la práctica se comporta como 204. No debe incluir cuerpo.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 205 Reset Content
206Partial ContentAlmacenable en caché por defecto
El servidor devuelve solo el rango o rangos de bytes que el cliente pidió con una cabecera Range.
Saltos en la reproducción de vídeo y audio, descargas reanudables y gestores de descargas que obtienen un archivo en fragmentos paralelos. Incluye Content-Range.
No lo envíes salvo que la solicitud tuviera una cabecera Range que estás respetando. Si ignoras Range, envía 200 con el cuerpo completo.
Almacenable en caché por defecto (de forma heurística)
GET /video.mp4 HTTP/1.1 Range: bytes=0-1023 HTTP/1.1 206 Partial Content Content-Range: bytes 0-1023/146515 Content-Length: 1024
207Multi-Status
El cuerpo (XML) contiene un estado independiente para cada uno de varios recursos.
WebDAV
Operaciones WebDAV como PROPFIND que actúan sobre muchos recursos. Algunas API JSON lo toman prestado para endpoints por lotes.
En las API por lotes, muchos equipos prefieren 200 con resultados por elemento, ya que los clientes genéricos tratan 207 como un éxito sin más.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 207 Multi-Status Content-Type: application/xml; charset="utf-8"
208Already Reported
Se usa dentro de una respuesta 207 para indicar que un recurso ya se listó antes, así que no se repite (evita bucles con bindings).
WebDAV
Servidores WebDAV compatibles con bindings (RFC 5842).
No tiene sentido como respuesta de nivel superior fuera de WebDAV.
Almacenable en caché solo con Cache-Control o Expires explícitos
<D:status>HTTP/1.1 208 Already Reported</D:status>
226IM Used
El servidor atendió un GET con un delta (manipulación de instancia) aplicado al recurso actual en lugar del recurso completo.
Codificación delta para HTTP (cabeceras A-IM / IM). Apenas se usa.
Los navegadores no lo admiten; no lo uses en API normales.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 226 IM Used IM: vcdiff ETag: "v2"
3xx Redirección
300Multiple ChoicesAlmacenable en caché por defecto
El recurso tiene varias representaciones y el cliente (o el usuario) debe elegir una.
Poco frecuente: negociación de contenido dirigida por el agente, por ejemplo ofrecer un documento en varios idiomas o formatos con enlaces a cada uno.
Los navegadores no eligen automáticamente. Para elegir idioma o formato funciona mejor la negociación dirigida por el servidor o una página normal con enlaces.
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 300 Multiple Choices Link: </doc.en.html>; rel=alternate; hreflang=en Link: </doc.fr.html>; rel=alternate; hreflang=fr
301Moved PermanentlyAlmacenable en caché por defecto
El recurso tiene una nueva URL permanente, indicada en la cabecera Location.
Cambios de dominio, de HTTP a HTTPS, slugs modificados, unificación de URL duplicadas. Los buscadores transfieren las señales de posicionamiento a la nueva URL.
Los navegadores pueden cambiar POST por GET al seguir un 301. Si hay que conservar el método (un endpoint de API que se ha movido), usa 308. Los navegadores almacenan los 301 en caché de forma agresiva, así que pruébalo antes de desplegar.
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 301 Moved Permanently Location: https://www.example.com/new-page
302Found
El recurso está temporalmente en otra URL; sigue usando la URL original en el futuro.
Redirecciones temporales: redirecciones de inicio de sesión, tests A/B, páginas de mantenimiento, redirecciones por ubicación o idioma.
Los navegadores cambian POST por GET al seguir un 302 (un comportamiento histórico que el RFC permite). Usa 303 para “ve a ver el resultado” tras un POST, y 307 cuando haya que conservar el método.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 302 Found Location: /login?next=%2Faccount
303See Other
Redirige al cliente a otra URL, que debe obtener con GET.
El patrón Post/Redirect/Get: tras el POST de un formulario, envía 303 a la página de resultado para que al recargar la página no se vuelva a enviar el formulario.
No es para contenido movido; no dice nada de que la URL original se haya movido.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 303 See Other Location: /orders/1234
304Not Modified
Respuesta a un GET o HEAD condicional (If-None-Match o If-Modified-Since): la copia en caché del cliente sigue siendo válida.
Revalidación de caché: no se almacena en sí, pero actualiza la respuesta en caché que el cliente ya tiene.
La envían automáticamente los servidores y las CDN cuando el ETag o la fecha Last-Modified coinciden, lo que ahorra transferir un cuerpo sin cambios.
Nunca envíes un cuerpo. No la envíes a una solicitud que no era condicional; el cliente no tiene nada que reutilizar.
No aplicable
GET /app.js HTTP/1.1 If-None-Match: "33a64df5" HTTP/1.1 304 Not Modified ETag: "33a64df5" Cache-Control: max-age=3600
305Use ProxyObsoleto
Obsoleto. Indicaba al cliente que repitiera la solicitud a través de un proxy indicado en Location.
Nada. Quedó obsoleto por motivos de seguridad y los navegadores lo ignoran.
No lo envíes.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 305 Use Proxy
306(Unused)Obsoleto
Reservado. Se usó en un borrador para "Switch Proxy" y ya no se utiliza.
Nada.
No lo envíes.
No aplicable
307Temporary Redirect
Redirección temporal en la que el cliente debe repetir la solicitud con el mismo método y el mismo cuerpo.
Redirigir temporalmente solicitudes POST, PUT o DELETE (un endpoint de API movido por mantenimiento). Los navegadores también muestran un 307 interno cuando HSTS obliga a usar HTTPS.
Para un traslado permanente, usa 308. Para "ve a obtener el resultado con GET", usa 303.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 307 Temporary Redirect Location: https://api2.example.com/v1/orders
308Permanent RedirectAlmacenable en caché por defecto
Redirección permanente en la que el cliente debe repetir la solicitud con el mismo método y el mismo cuerpo.
Un endpoint de API movido de forma permanente que recibe POST o PUT. Los buscadores lo tratan como un 301. Next.js y Vercel usan 308 por defecto para las redirecciones permanentes.
Los clientes muy antiguos (Internet Explorer en Windows 7 y anteriores) no lo entienden; para simples traslados de páginas, 301 funciona igual de bien.
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 308 Permanent Redirect Location: https://example.com/api/v2/upload
4xx Error del cliente
400Bad Request
El servidor no procesará la solicitud por un error del cliente: sintaxis mal formada, encuadre no válido o parámetros no válidos.
JSON imposible de analizar, falta un parámetro obligatorio, un valor de tipo incorrecto. Explica el problema en el cuerpo (problem+json de RFC 9457 es un buen formato).
Para una entrada bien formada que no cumple las reglas de negocio, muchas API usan 422. Para problemas de autenticación usa 401 o 403.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{"title": "Invalid JSON", "detail": "Unexpected token } at position 41"}401Unauthorized
La solicitud no tiene credenciales de autenticación válidas. A pesar del nombre, significa "no autenticado".
Sin token, con un token caducado o con una contraseña incorrecta. La respuesta debe incluir una cabecera WWW-Authenticate que describa cómo autenticarse.
Si el usuario ha iniciado sesión pero no tiene permiso, usa 403. No envíes 401 sin WWW-Authenticate.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer realm="api", error="invalid_token"
402Payment Required
Reservado para uso futuro. No tiene una semántica estándar.
Algunas API lo usan para "cuota agotada, mejora tu plan" o para un pago fallido (Stripe devuelve 402 en las solicitudes con tarjeta rechazada).
No cuentes con que los clientes lo entiendan; describe el problema en el cuerpo.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 402 Payment Required
Content-Type: application/json
{"error": "card_declined"}403Forbidden
El servidor entendió la solicitud y sabe quién eres (o le da igual), pero se niega a atenderla.
El usuario autenticado no tiene permiso, una IP está bloqueada, el listado de directorios está desactivado o ha saltado una regla del WAF. Volver a autenticarse no servirá de nada.
Si faltan las credenciales o no son válidas, usa 401. Si revelar que el recurso existe ya es en sí una filtración, devuelve 404.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 403 Forbidden
Content-Type: application/json
{"error": "You do not have access to this project"}404Not FoundAlmacenable en caché por defecto
El servidor no tiene una representación actual para la URL, o no quiere decir si existe.
URL desconocidas, registros eliminados cuando no llevas un control de eliminaciones, u ocultar recursos a usuarios no autorizados.
Si el recurso existió y ha desaparecido para siempre, 410 lo indica explícitamente. No devuelvas una página 200 que diga "no encontrado" (un soft 404).
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 404 Not Found Content-Type: text/html
405Method Not AllowedAlmacenable en caché por defecto
La URL existe, pero no admite este método HTTP.
Un DELETE a un recurso de solo lectura o un POST a una página que solo admite GET. La respuesta debe incluir una cabecera Allow con los métodos admitidos.
No lo uses para problemas de permisos (403) ni para métodos que el servidor no implementa en absoluto (501).
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 405 Method Not Allowed Allow: GET, HEAD
406Not Acceptable
El servidor no puede generar una respuesta que coincida con las cabeceras Accept, Accept-Language o Accept-Encoding de la solicitud.
Una API que solo habla JSON y recibe "Accept: application/xml" sin alternativa.
La mayoría de los servidores ignoran las cabeceras Accept que no coinciden y envían su formato predeterminado, lo que suele ser más amable.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 406 Not Acceptable
Content-Type: application/json
{"supported": ["application/json"]}407Proxy Authentication Required
Como 401, pero el cliente debe autenticarse ante el proxy intermedio.
Lo envían los proxies de reenvío (proxies corporativos), con una cabecera Proxy-Authenticate.
Los servidores de origen nunca deberían enviarlo.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 407 Proxy Authentication Required Proxy-Authenticate: Basic realm="corp-proxy"
408Request Timeout
El servidor no recibió una solicitud completa en el tiempo que estaba dispuesto a esperar y va a cerrar la conexión.
Lo envían los servidores en conexiones keep-alive inactivas o en subidas lentas. Los clientes pueden reintentar la solicitud en una conexión nueva.
No es para un procesamiento lento en el backend; eso es un 504 en una pasarela o simplemente una respuesta lenta. Envía "Connection: close" con él.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 408 Request Timeout Connection: close
409Conflict
La solicitud entra en conflicto con el estado actual del recurso.
Crear un usuario cuyo correo ya existe, editar un registro que otra persona ha cambiado (versión no coincidente), eliminar una carpeta que no está vacía.
Para condiciones If-Match / If-Unmodified-Since que fallan, usa 412. Para errores de validación, usa 400 o 422.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 409 Conflict
Content-Type: application/json
{"error": "Email already registered"}410GoneAlmacenable en caché por defecto
El recurso existía aquí, ha desaparecido de forma permanente y no tiene dirección de reenvío.
Productos descatalogados, promociones caducadas, cuentas eliminadas, versiones de API retiradas. Google trata 404 y 410 casi igual, aunque un 410 puede salir del índice algo antes.
Si el contenido se ha movido, redirige con 301. Si no estás seguro de que sea permanente, usa 404.
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 410 Gone
411Length Required
El servidor requiere una cabecera Content-Length en esta solicitud.
Servidores que rechazan las subidas fragmentadas y necesitan saber de antemano el tamaño del cuerpo.
Las aplicaciones rara vez lo necesitan; normalmente lo emite el propio servidor web.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 411 Length Required
412Precondition Failed
Una condición de las cabeceras de la solicitud (If-Match, If-Unmodified-Since, If-None-Match en una escritura) se evaluó como falsa.
Concurrencia optimista: el cliente envió If-Match con un ETag antiguo, lo que significa que otra persona cambió el recurso antes.
No lo uses para incumplimientos de reglas de negocio que no tienen nada que ver con cabeceras condicionales (409 o 422).
Almacenable en caché solo con Cache-Control o Expires explícitos
PUT /docs/7 HTTP/1.1 If-Match: "v3" HTTP/1.1 412 Precondition Failed ETag: "v4"
413Content Too Large
El cuerpo de la solicitud es más grande de lo que el servidor está dispuesto a procesar. Se llamaba "Payload Too Large" antes de RFC 9110.
Subidas por encima del límite (client_max_body_size de nginx, un tope de 10 MB en una API). Si el límite es temporal, añade Retry-After.
Para una URL demasiado larga usa 414; para cabeceras demasiado grandes, 431.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 413 Content Too Large Connection: close
414URI Too LongAlmacenable en caché por defecto
El destino de la solicitud (URL) es más largo de lo que el servidor está dispuesto a interpretar.
Cadenas de consulta enormes, a menudo un formulario GET que debería ser POST, o un bucle de redirección que va añadiendo parámetros.
Pasa las entradas grandes al cuerpo de la solicitud (POST) en lugar de subir el límite sin fin.
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 414 URI Too Long
415Unsupported Media Type
El servidor rechaza la solicitud porque el formato del cuerpo (Content-Type o Content-Encoding) no es compatible.
Un endpoint que acepta JSON y recibe datos de formulario o XML, o falta la cabecera Content-Type. Incluye Accept-Post o Accept-Patch para indicar qué se admite.
No es para un cuerpo con el formato correcto pero contenido no válido (400 o 422).
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 415 Unsupported Media Type Accept-Post: application/json
416Range Not Satisfiable
Ninguno de los rangos de bytes de la cabecera Range coincide con el recurso, por ejemplo al pedir bytes más allá del final del archivo.
Descargas reanudadas en las que el archivo ha encogido o el cliente pide más allá del final. Incluye Content-Range: bytes */<length>.
Los servidores pueden simplemente ignorar un Range no válido y devolver 200 con el cuerpo completo, algo que también está permitido.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 416 Range Not Satisfiable Content-Range: bytes */47022
417Expectation Failed
El servidor no puede cumplir el requisito de la cabecera Expect de la solicitud.
Un cliente envió "Expect: 100-continue" a un servidor o proxy que no lo admite, o una expectativa desconocida.
Los clientes que lo reciben deberían reintentar sin la cabecera Expect.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 417 Expectation Failed
418(Unused)
Reservado por RFC 9110 porque 418 se extendió mucho como el código de broma “I’m a teapot”; no tiene un significado definido en HTTP.
Reservado. Famoso como “I’m a teapot” (soy una tetera) por el RFC 2324 (HTCPCP), la broma del Día de los Inocentes de 1998.
Solo como easter egg. Algunos servicios lo usan para responder con humor a solicitudes que quieren rechazar.
No lo uses para errores reales; no se le puede asignar un significado y los clientes no sabrán qué hacer.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 418 I'm a teapot
419Page ExpiredNo oficial · Laravel
Laravel lo devuelve cuando falta el token CSRF o ha caducado, normalmente después de que expire la sesión en una página con un formulario.
Lo envía el middleware CSRF de Laravel. Se soluciona recargando la página, incluyendo @csrf en los formularios o enviando la cabecera X-CSRF-TOKEN con las solicitudes AJAX.
No es un código estándar; no lo envíes desde API que no sean de Laravel.
No aplicable
Laravel (no está en el registro de IANA)
HTTP/1.1 419 unknown status
420Enhance Your CalmNo oficial · Twitter (antiguo)
La respuesta de límite de frecuencia de la antigua API de Twitter, sustituida por el estándar 429.
Nada nuevo. Aún puedes encontrarlo en bibliotecas cliente antiguas. Spring definió en su día 420 "Method Failure", ahora obsoleto.
Usa 429 para la limitación de frecuencia.
No aplicable
Twitter API v1 (no está en el registro de IANA)
HTTP/1.1 420 Enhance Your Calm
421Misdirected Request
La solicitud llegó a un servidor que no puede generar una respuesta para ese host y esquema.
La fusión de conexiones de HTTP/2 salió mal: el navegador reutilizó una conexión para otro nombre de host cubierto por el mismo certificado, pero el servidor no lo sirve. El cliente debería reintentar en una conexión nueva.
No es para nombres de host desconocidos normales en un único servidor; eso suele ser un 404 o el host virtual predeterminado.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/2 421
422Unprocessable Content
La solicitud está bien formada y en un formato admitido, pero su contenido no supera la validación. Se llama "Unprocessable Entity" en RFC 4918.
Errores de validación de formularios y API: un correo que no es un correo, una fecha de fin anterior a la de inicio. Rails, Laravel y FastAPI lo usan por defecto.
Para sintaxis mal formada (JSON imposible de analizar) usa 400.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 422 Unprocessable Content
Content-Type: application/json
{"errors": {"email": ["is invalid"]}}423Locked
El recurso está bloqueado, así que la solicitud no puede modificarlo.
WebDAV
Semántica LOCK de WebDAV. Algunas API lo usan para registros que otra persona está editando o para cuentas bloqueadas tras varios inicios de sesión fallidos.
Fuera de WebDAV, los clientes genéricos entienden mejor 409.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 423 Locked
424Failed Dependency
La acción falló porque falló otra acción de la que dependía.
WebDAV
En un PROPPATCH de WebDAV o en una solicitud por lotes, los elementos que no se intentaron porque falló uno anterior.
No es para fallos de servicios upstream; esos son 502 o 503.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 424 Failed Dependency
425Too Early
El servidor no procesará una solicitud enviada en early data de TLS 1.3 (0-RTT) porque podría repetirse.
CDN y servidores que aceptan 0-RTT pero rechazan solicitudes no idempotentes (POST) en early data. El cliente reintenta cuando termina el handshake.
No es un código genérico de "inténtalo más tarde"; para eso usa 503 con Retry-After.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 425 Too Early
426Upgrade Required
El servidor rechaza la solicitud con el protocolo actual, pero la aceptaría tras una actualización indicada en la cabecera Upgrade.
Exigir TLS o un protocolo más nuevo, o un endpoint WebSocket al que llega una solicitud HTTP normal. Debe incluir una cabecera Upgrade.
Para pasar de HTTP a HTTPS en sitios web, lo habitual es una redirección 301 o 308 más HSTS.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 426 Upgrade Required Upgrade: TLS/1.3, HTTP/1.1 Connection: Upgrade
428Precondition Required
El servidor exige que la solicitud sea condicional (If-Match, etc.) para evitar actualizaciones perdidas.
API que obligan a los clientes a enviar If-Match con el último ETag que vieron antes de un PUT, PATCH o DELETE.
Usa 412 cuando se envió una condición previa y falló; 428 es para cuando no se envió ninguna.
Las cachés no deben almacenarlo
HTTP/1.1 428 Precondition Required
Content-Type: application/json
{"error": "Send If-Match with the current ETag"}429Too Many Requests
El cliente envió demasiadas solicitudes en un tiempo determinado (limitación de frecuencia).
Límites de frecuencia de API, limitación de inicios de sesión, protección contra scraping. Incluye Retry-After para que los clientes bien diseñados sepan cuándo volver; las cabeceras RateLimit también ayudan.
Si el servidor está sobrecargado para todos, usa 503. Googlebot trata 429 como 503 y reduce el rastreo.
Las cachés no deben almacenarlo
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
{"error": "Rate limit exceeded: 100 requests per minute"}431Request Header Fields Too Large
Las cabeceras, por separado o en conjunto, son demasiado grandes para el servidor.
Normalmente cookies demasiado grandes acumuladas en un dominio o tokens de Authorization enormes. Borrar las cookies suele solucionarlo para los usuarios.
Para una URL larga usa 414; para un cuerpo grande, 413.
Las cachés no deben almacenarlo
HTTP/1.1 431 Request Header Fields Too Large
440Login Time-outNo oficial · Microsoft IIS / Exchange
La sesión del cliente ha caducado y debe volver a iniciar sesión (Outlook Web Access y otras aplicaciones IIS).
Se ve en entornos Exchange/OWA.
Usa 401 para las sesiones caducadas en tus propias aplicaciones.
No aplicable
Microsoft IIS (no está en el registro de IANA)
HTTP/1.1 440 Login Time-out
444No ResponseNo oficial · nginx
Código interno de nginx: "return 444;" cierra la conexión sin enviar ninguna respuesta.
Descartar solicitudes de escáneres, solicitudes con cabeceras Host desconocidas en un bloque server predeterminado o clientes abusivos. Aparece en los registros de nginx; el cliente ve una respuesta vacía.
El cliente nunca recibe un 444, así que no es algo que haya que gestionar en el código del cliente.
No aplicable
nginx (no está en el registro de IANA)
server {
listen 80 default_server;
return 444;
}449Retry WithNo oficial · Microsoft
Extensión de Microsoft: la solicitud debe reintentarse después de que el cliente realice una acción concreta.
Se ve en algunos servicios de Microsoft (Exchange ActiveSync; Azure Cosmos DB usa 449 para conflictos de escritura que se pueden reintentar).
No es estándar; usa 409 o 503 con Retry-After en tus propias API.
No aplicable
Microsoft IIS (no está en el registro de IANA)
HTTP/1.1 449 Retry With
450Blocked by Windows Parental ControlsNo oficial · Microsoft
El Control parental de Windows bloqueó el acceso a la página.
Se genera en sistemas Windows con control parental.
No lo envíes desde servidores.
No aplicable
Microsoft (no está en el registro de IANA)
HTTP/1.1 450 Blocked by Windows Parental Controls
451Unavailable For Legal ReasonsAlmacenable en caché por defecto
Se deniega el acceso por una exigencia legal: una orden judicial, censura gubernamental o una restricción geográfica por motivos legales.
Contenido bloqueado en una jurisdicción (sanciones, bloqueos geográficos relacionados con el RGPD, órdenes de retirada). Una cabecera Link con rel="blocked-by" puede indicar quién lo impuso.
No es para denegaciones de permiso normales (403) ni para contenido que simplemente decidiste retirar (410).
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 451 Unavailable For Legal Reasons Link: <https://authority.example/>; rel="blocked-by"
460Client closed connection (AWS ELB)No oficial · AWS Application Load Balancer
Un ALB de AWS lo registra cuando el cliente cerró la conexión antes de que transcurriera el tiempo de espera de inactividad.
Se ve en los registros de acceso del ALB; normalmente un cliente con un tiempo de espera más corto que el tiempo de procesamiento del destino.
No se envía a los clientes.
No aplicable
AWS Elastic Load Balancing (no está en el registro de IANA)
elb_status_code=460
463Too many IPs in X-Forwarded-For (AWS ELB)No oficial · AWS Application Load Balancer
El ALB recibió una cabecera X-Forwarded-For con más de 30 direcciones IP.
Normalmente un bucle de proxies que va añadiendo direcciones.
No es para uso en aplicaciones.
No aplicable
AWS Elastic Load Balancing (no está en el registro de IANA)
HTTP/1.1 463
494Request Header Too LargeNo oficial · nginx
Código interno de nginx para cabeceras que superan large_client_header_buffers; el cliente recibe un 400.
Aparece en los registros de nginx y en la configuración de error_page.
El código estándar es 431.
No aplicable
nginx (no está en el registro de IANA)
error_page 494 /header-too-large.html;
495SSL Certificate ErrorNo oficial · nginx
Interno de nginx: el cliente presentó un certificado de cliente no válido (TLS mutuo). Se envía al cliente como 400.
Páginas de error personalizadas para fallos de mTLS.
No es un código de estado que viaje por la red.
No aplicable
nginx (no está en el registro de IANA)
error_page 495 /bad-client-cert.html;
496SSL Certificate RequiredNo oficial · nginx
Interno de nginx: se requería un certificado de cliente, pero no se proporcionó. Se envía al cliente como 400.
Páginas de error personalizadas cuando ssl_verify_client está activado.
No es un código de estado que viaje por la red.
No aplicable
nginx (no está en el registro de IANA)
error_page 496 /client-cert-required.html;
497HTTP Request Sent to HTTPS PortNo oficial · nginx
Interno de nginx: llegó una solicitud HTTP normal a un puerto que espera TLS. Se envía al cliente como 400.
Un truco habitual es "error_page 497 =301 https://$host$request_uri;" para redirigir esas solicitudes a HTTPS.
No es un código de estado que viaje por la red.
No aplicable
nginx (no está en el registro de IANA)
error_page 497 =301 https://$host:$server_port$request_uri;
498Invalid TokenNo oficial · Esri ArcGIS Server
ArcGIS lo devuelve para un token caducado o no válido por otro motivo.
Solo es relevante al llamar a servicios de ArcGIS.
Usa 401 para tokens no válidos en tus propias API.
No aplicable
Esri ArcGIS (no está en el registro de IANA)
HTTP/1.1 498 Invalid Token
499Client Closed RequestNo oficial · nginx
nginx registra 499 cuando el cliente cerró la conexión antes de que nginx enviara una respuesta.
Se ve en los registros de acceso: usuarios que abandonan la página, clientes móviles que agotan el tiempo de espera o un balanceador de carga delante de nginx con un tiempo de espera más corto. Muchos 499 en un mismo endpoint suelen indicar que es demasiado lento.
El cliente nunca lo recibe. Esri también usa 499 para "Token Required".
No aplicable
nginx (no está en el registro de IANA)
203.0.113.9 - - [16/Oct/2026:10:12:01 +0000] "GET /report HTTP/1.1" 499 0
5xx Error del servidor
500Internal Server Error
El servidor se encontró con una condición inesperada que le impidió atender la solicitud.
Excepciones no controladas y errores de programación. Es la opción genérica cuando no se aplica ningún 5xx más específico.
No lo uses para errores del cliente (4xx). No expongas trazas de la pila en el cuerpo en producción; regístralas.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 500 Internal Server Error
Content-Type: application/problem+json
{"title": "Internal Server Error", "traceId": "4bf92f35"}501Not ImplementedAlmacenable en caché por defecto
El servidor no admite la funcionalidad necesaria, normalmente un método HTTP que no reconoce en absoluto.
Una solicitud con un método desconocido (p. ej., un método WebDAV en un servidor web normal), o una función que el servidor aún no ha implementado a propósito.
Si el método se conoce pero no está permitido en esta URL, usa 405.
Almacenable en caché por defecto (de forma heurística)
HTTP/1.1 501 Not Implemented
502Bad Gateway
Una pasarela o proxy recibió una respuesta no válida del servidor upstream.
Lo envían los proxies inversos y los balanceadores de carga (nginx, Cloudflare, AWS ALB) cuando el servidor de la aplicación se ha caído, ha cerrado la conexión o ha devuelto basura.
El código de la aplicación rara vez necesita enviarlo, salvo las pasarelas de API que llaman a otro servicio que ha fallado.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 502 Bad Gateway Server: nginx
503Service Unavailable
El servidor no puede atender la solicitud ahora mismo: está sobrecargado o en mantenimiento. Se espera que sea temporal.
Mantenimiento programado, descarte de carga, caída de una dependencia. Añade Retry-After. Los buscadores mantienen la página indexada durante periodos cortos de 503, a diferencia de una página de mantenimiento con 200 o un 404.
No dejes un sitio en 503 durante días; Google acaba eliminando las URL que lo siguen devolviendo.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 503 Service Unavailable Retry-After: 3600
504Gateway Timeout
Una pasarela o proxy no recibió a tiempo una respuesta del servidor upstream.
Lo envían los proxies y balanceadores de carga cuando la aplicación tarda más que el tiempo de espera del proxy (proxy_read_timeout de nginx es de 60 segundos por defecto).
Para trabajos largos, no te limites a subir los tiempos de espera; devuelve 202 y procesa de forma asíncrona.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 504 Gateway Timeout Server: awselb/2.0
505HTTP Version Not Supported
El servidor no admite la versión principal de HTTP usada en la solicitud.
Un servidor que recibe una versión de protocolo que no sabe hablar.
Se ve poco; los clientes negocian HTTP/2 y HTTP/3 mediante ALPN y Alt-Svc en lugar de a base de pruebas.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 505 HTTP Version Not Supported
506Variant Also Negotiates
Error de configuración del servidor: la variante elegida está configurada a su vez para negociar, lo que crea un bucle.
Negociación de contenido transparente (experimental)
Solo en servidores que implementan la negociación de contenido transparente de RFC 2295.
No es para errores de la aplicación.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 506 Variant Also Negotiates
507Insufficient Storage
El servidor no puede almacenar lo necesario para completar la solicitud.
WebDAV
API de WebDAV o de almacenamiento de archivos cuando el disco o la cuota del usuario están llenos.
Para una sola subida que supera un límite de tamaño, 413 es más claro.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 507 Insufficient Storage
508Loop Detected
El servidor detuvo una operación porque encontró un bucle infinito (bindings de WebDAV con Depth: infinity).
WebDAV
Servidores WebDAV. Los hostings compartidos basados en CloudLinux también envían 508 "Resource Limit Is Reached" cuando una cuenta alcanza sus límites, algo que no es estándar.
No es para bucles de redirección; esos son un error del lado del cliente que el propio navegador notifica.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 508 Loop Detected
509Bandwidth Limit ExceededNo oficial · Apache bw_mod / cPanel
La cuenta de hosting ha superado su asignación de ancho de banda.
Paneles de control de hosting compartido.
Usa 503 o 429 en tus propios sistemas.
No aplicable
Apache / cPanel (no está en el registro de IANA)
HTTP/1.1 509 Bandwidth Limit Exceeded
510Not ExtendedObsoleto
La solicitud no cumplía la política de acceso al recurso según el HTTP Extension Framework.
Marcado como obsoleto en el registro de IANA: RFC 2774 pasó a Historic.
Nada actual; el framework de extensiones nunca se llegó a implementar de forma generalizada.
No lo envíes.
Almacenable en caché solo con Cache-Control o Expires explícitos
HTTP/1.1 510 Not Extended
511Network Authentication Required
El cliente debe autenticarse para obtener acceso a la red: un portal cautivo.
Portales wifi de hoteles, aeropuertos y cafeterías que interceptan el tráfico hasta que el usuario inicia sesión o acepta las condiciones.
Los servidores de origen nunca deben enviarlo; es solo para proxies de red que interceptan el tráfico.
Las cachés no deben almacenarlo
HTTP/1.1 511 Network Authentication Required Content-Type: text/html <meta http-equiv="refresh" content="0; url=https://login.example.net/">
520Web Server Returned an Unknown ErrorNo oficial · Cloudflare
El origen devolvió a Cloudflare una respuesta vacía, desconocida o inesperada.
Revisa los registros del origen: caídas, conexiones reiniciadas, cabeceras que superan el límite de Cloudflare o una respuesta vacía.
Solo lo envía Cloudflare.
No aplicable
Cloudflare (no está en el registro de IANA)
HTTP/2 520 server: cloudflare
521Web Server Is DownNo oficial · Cloudflare
Cloudflare no pudo conectarse al origen: la conexión fue rechazada.
El servidor web de origen está detenido o un firewall bloquea los rangos de IP de Cloudflare.
Solo lo envía Cloudflare.
No aplicable
Cloudflare (no está en el registro de IANA)
HTTP/2 521 server: cloudflare
522Connection Timed OutNo oficial · Cloudflare
Cloudflare agotó el tiempo de espera al establecer una conexión TCP con el origen.
Origen sobrecargado, paquetes descartados por un firewall o una IP de origen incorrecta en el DNS.
Solo lo envía Cloudflare.
No aplicable
Cloudflare (no está en el registro de IANA)
HTTP/2 522 server: cloudflare
523Origin Is UnreachableNo oficial · Cloudflare
Cloudflare no puede llegar en absoluto al origen, normalmente por un problema de enrutamiento o un registro DNS incorrecto.
Comprueba que los registros DNS A/AAAA apuntan a la IP correcta y accesible.
Solo lo envía Cloudflare.
No aplicable
Cloudflare (no está en el registro de IANA)
HTTP/2 523 server: cloudflare
524A Timeout OccurredNo oficial · Cloudflare
Cloudflare se conectó al origen, pero este no envió una respuesta HTTP dentro del tiempo de espera (100 segundos por defecto).
Solicitudes de larga duración: pasa el trabajo a una tarea en segundo plano y consulta su estado, o transmite el progreso.
Solo lo envía Cloudflare.
No aplicable
Cloudflare (no está en el registro de IANA)
HTTP/2 524 server: cloudflare
525SSL Handshake FailedNo oficial · Cloudflare
Falló el handshake TLS entre Cloudflare y el origen.
El origen no escucha en el 443, no tiene certificado, no comparte ningún conjunto de cifrado o SNI no está configurado, mientras el modo SSL es Full o Full (strict).
Solo lo envía Cloudflare.
No aplicable
Cloudflare (no está en el registro de IANA)
HTTP/2 525 server: cloudflare
526Invalid SSL CertificateNo oficial · Cloudflare
En modo Full (strict), Cloudflare no pudo validar el certificado del origen: caducado, autofirmado o con un nombre de host incorrecto.
Instala un certificado válido o un certificado Cloudflare Origin CA en el origen.
Solo lo envía Cloudflare.
No aplicable
Cloudflare (no está en el registro de IANA)
HTTP/2 526 server: cloudflare
527Railgun ErrorNo oficial · Cloudflare (retirado)Obsoleto
Problema de conexión entre Cloudflare y un listener de Railgun en el origen. Cloudflare ha dejado de ofrecer Railgun.
Solo histórico.
Solo lo enviaba Cloudflare.
No aplicable
Cloudflare (no está en el registro de IANA)
HTTP/1.1 527 Railgun Error
530Origin DNS / 1xxx errorNo oficial · Cloudflare
Se devuelve con una página de error 1xxx de Cloudflare (como 1016 Origin DNS error); el código 1xxx que aparece en la página es la causa real.
Busca el número de error 1xxx que aparece en la página.
Solo lo envían CDN y proveedores de hosting.
No aplicable
Cloudflare (no está en el registro de IANA)
HTTP/2 530 server: cloudflare
561Unauthorized (AWS ELB)No oficial · AWS Application Load Balancer
La autenticación integrada del ALB (OIDC o Cognito) falló con el proveedor de identidad.
Revisa la configuración del IdP en la regla del listener del ALB.
No es para uso en aplicaciones.
No aplicable
AWS Elastic Load Balancing (no está en el registro de IANA)
HTTP/1.1 561
598Network Read Timeout ErrorNo oficial · Algunos proxies HTTP
Algunos proxies lo usan para indicar un tiempo de espera de lectura agotado detrás del proxy.
Poco frecuente; puedes verlo en ciertos productos de proxy.
Usa 504.
No aplicable
Informal convention (no está en el registro de IANA)
HTTP/1.1 598
599Network Connect Timeout ErrorNo oficial · Algunos proxies y clientes HTTP
Algunos proxies y bibliotecas cliente (el cliente HTTP de Tornado, por ejemplo) lo usan para un tiempo de espera de conexión agotado.
Poco frecuente.
Usa 504 para proxies.
No aplicable
Informal convention (no está en el registro de IANA)
HTTP/1.1 599
Una referencia estática que funciona en tu navegador; tus búsquedas no se envían a ningún sitio. Ver todas las herramientas gratis.
¿Encontraste un problema o algo que podría mejorar? Leemos todos los mensajes y lo arreglamos rápido.
Esta lista de códigos de estado HTTP cubre todos los códigos del registro de la IANA, desde 100 Continue hasta 511 Network Authentication Required, con su significado, cuándo usarlo, cuándo no, si las cachés pueden almacenarlo y la sección del RFC que lo define. Escribe un número, una clase como 4xx o una palabra como “redirect” o “rate limit” para filtrar, y enlaza directamente a cualquier código con un ancla como #404 o #503.
Las entradas oficiales siguen el RFC 9110 (2022), que sustituyó al RFC 7231 y cambió el nombre de algunos códigos: 413 ahora es Content Too Large y 422 es Unprocessable Content. Los códigos que ves en los logs pero no encontrarás en el registro, como el 499 de nginx o el 522 de Cloudflare, también se incluyen, marcados como no oficiales y con el sistema que los envía. Es una referencia, no un monitor: no consulta URL ni comprueba qué estado devuelve un sitio en producción.
Cómo usarla
- Escribe un código (503), una clase (4xx) o una palabra clave (timeout, redirect, cache) en el cuadro de búsqueda. Los resultados se filtran mientras escribes.
- Usa los botones de clase para ver solo los códigos 1xx, 2xx, 3xx, 4xx o 5xx, y desmarca “Incluir códigos no oficiales” para ocultar los específicos de cada proveedor.
- Haz clic en un código para desplegarlo: significado, cuándo usarlo, cuándo no, comportamiento de caché, el RFC que lo define y una respuesta de ejemplo.
- Usa “Copiar el enlace a este código” para compartir un enlace directo como /tools/http-status-codes#429.
Preguntas frecuentes
¿Qué diferencia hay entre 401 y 403?
401 Unauthorized significa que la solicitud no tiene credenciales válidas: el cliente no ha iniciado sesión o el token ha caducado. El servidor debe enviar una cabecera WWW-Authenticate que indique cómo autenticarse. 403 Forbidden significa que el servidor sabe quién es el cliente, o no necesita saberlo, y aun así se niega; volver a iniciar sesión no servirá de nada. En resumen, 401 es “¿quién eres?” y 403 es “ya lo sé, y no”.
¿Debo usar 301 o 308 para una redirección permanente?
Ambos son permanentes y ambos transmiten las señales de posicionamiento en Google. La diferencia está en el método: al seguir un 301, los navegadores pueden convertir un POST en un GET, mientras que el 308 obliga al cliente a repetir el mismo método y el mismo cuerpo. Para mover páginas normales basta con 301; para un endpoint de API que recibe POST o PUT, usa 308. La misma pareja existe para las redirecciones temporales: 302 puede cambiar el método y 307 no debe hacerlo.
¿Qué significa 499 en los logs de nginx?
499 Client Closed Request es un código exclusivo de nginx. Se registra cuando el cliente cierra la conexión antes de que nginx envíe una respuesta, así que el cliente nunca llega a recibir un 499. Algunos 499 ocasionales son usuarios que abandonan la página; muchos en un mismo endpoint suelen indicar que es demasiado lento y que los clientes o un balanceador de carga anterior agotan antes su tiempo de espera.
¿Qué diferencia hay entre 502, 503 y 504?
Los tres proceden de un servidor situado delante de otro. 502 Bad Gateway significa que el proxy recibió una respuesta no válida o una conexión cortada de la aplicación de origen. 503 Service Unavailable significa que el servidor no puede atender solicitudes temporalmente, normalmente por sobrecarga o mantenimiento, y debería incluir Retry-After. 504 Gateway Timeout significa que el proxy se cansó de esperar la respuesta del servidor de origen.
¿Es 418 I'm a teapot un código de estado real?
Empezó como una broma del Día de los Inocentes (1 de abril) en el RFC 2324 (1998) y lo implementó tanto software que el RFC 9110 incluye ahora el 418 como “(Unused)”: reservado para que nunca reciba un significado real. No es un error que debas enviar para problemas reales, pero puedes mantenerlo sin problema en un easter egg.
¿Qué códigos de estado se pueden almacenar en caché por defecto?
El RFC 9110 señala 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414 y 501 como almacenables en caché de forma heurística, lo que significa que una caché puede guardarlos incluso sin Cache-Control ni Expires. El RFC 7725 añade el 451. Los demás códigos, incluidos el 302 y el 307, solo se almacenan en caché cuando la respuesta incluye información de vigencia explícita, y el RFC 6585 establece que 428, 429, 431 y 511 no deben almacenarse en ningún caso.
Las cinco clases de un vistazo
• 1xx Informativos: respuestas provisionales antes de la definitiva. Rara vez los gestionas directamente; 101 (cambio a WebSocket) y 103 (Early Hints) son los que importan en la práctica.
• 2xx Éxito: la solicitud ha funcionado. 200 para una respuesta normal, 201 cuando se ha creado algo (con una cabecera Location), 204 cuando deliberadamente no hay cuerpo.
• 3xx Redirección: el cliente debe buscar en otro sitio. 301/308 para traslados permanentes, 302/307 para temporales, 303 tras el POST de un formulario, 304 cuando la copia en caché sigue siendo válida.
• 4xx Error del cliente: la solicitud es incorrecta y repetirla sin cambios volverá a fallar. 400 mal formada, 401 sin autenticar, 403 no permitida, 404 no encontrada, 409 conflicto, 422 validación fallida, 429 límite de solicitudes superado.
• 5xx Error del servidor: la solicitud puede ser correcta, pero el servidor ha fallado. 500 es un bug, 502/504 son fallos entre el proxy y el servidor de origen y 503 es una indisponibilidad temporal.
Cómo elegir el código adecuado en una API
Devuelve el código más específico sobre el que pueda actuar un cliente genérico y pon el detalle en el cuerpo. Un cliente HTTP con reintentos, un CDN o un sistema de monitorización saben qué significan 429 y 503 sin leer tu JSON, pero no pueden interpretar un 200 con {"error": true}. El RFC 9457 (Problem Details) define una estructura JSON estándar para los cuerpos de error.
Una correspondencia práctica para la mayoría de las API JSON: 400 para entradas que no se pueden analizar, 422 para entradas bien formadas que no superan la validación, 401 cuando el token falta o ha caducado, 403 cuando el usuario no tiene permiso, 404 para ID desconocidos (también para ocultar recursos que un usuario no puede ver), 409 para duplicados y conflictos de versión, 412 cuando un ETag de If-Match está desactualizado, 429 con Retry-After para límites de solicitudes y 503 con Retry-After para paradas programadas.
No inventes números nuevos. Los clientes tratan un código desconocido como el x00 de su clase (un 4xx desconocido se gestiona como un 400), así que un 461 personalizado no te aporta nada frente a un 400 con un mensaje claro.
Códigos de estado y SEO
Los buscadores interpretan los códigos de estado al pie de la letra. Un 301 o 308 transfiere las señales de la URL antigua a la nueva; un 302 o 307 indica a Google que mantenga indexada la URL antigua. Tanto el 404 como el 410 eliminan una página del índice con el tiempo. Una página con 200 que dice “no encontrado” es un soft 404, que Google detecta y notifica en Search Console. Para un mantenimiento, un periodo corto de 503 con Retry-After mantiene intacto el posicionamiento, mientras que una página con 200 que diga “volvemos enseguida” puede sustituir tu contenido en los resultados de búsqueda. Googlebot también reduce su frecuencia de rastreo cuando ve 429, 500 o 503.
Herramientas gratis relacionadas
- Analizador de user agent — Consulta tu propio user agent y tus client hints, o analiza cualquier cadena UA para obtener navegador, motor, SO, dispositivo y CPU. Modo por lotes con CSV.
- Formateador JSON — Formatea, minifica y valida JSON, con los errores de análisis localizados por línea y columna. En tu navegador, sin subir nada.
- Docker Run ⇄ Compose — Convierte un comando docker run en un servicio de docker-compose.yml, o un servicio de Compose de vuelta en docker run.
- Probador de regex — Prueba una expresión regular con un texto de ejemplo, con resaltado de coincidencias en vivo, grupos de captura y vista previa de reemplazo. Gratis, en tu navegador.