DiseñoEstados de error en UX: qué mostrar cuando falla una petición
Una petición puede fallar de seis maneras, del campo rechazado a la conexión caída. Qué mostrar en cada caso, cómo hacer seguro el reintento y qué escribir.

La ruta de error es todo lo que un producto muestra cuando una petición no sale bien: el mensaje, dónde aparece, qué pasa con el trabajo que se acaba de hacer y la acción que devuelve al usuario a su tarea. Cubre seis fallos distintos, desde un campo que el servidor rechaza hasta una conexión que se cae a mitad de un guardado. Cada uno necesita su propia pantalla. Conviene diseñarla antes del lanzamiento, porque en producción quien se la encuentra primero es alguien en mitad de su trabajo, no un tester.
¿Por qué la ruta de error decide si un producto inspira confianza?
Un fallo cuesta dos veces: la petición perdida y el tiempo que se tarda en entender qué ha pasado. Las pruebas de Baymard Institute sobre checkout detectaron que los mensajes de error inesperados contribuían al abandono de formularios, y que el 31% de los sitios analizados no tenía ninguna validación en línea. El dato es de checkouts de e-commerce. Un formulario SaaS que guarda una factura o invita a un compañero funciona igual, y se abandona igual.
El coste más difícil es la confianza. Quien ha perdido diez minutos de texto por un timeout tiene un buen motivo para copiarlo en otro sitio antes de pulsar Guardar la próxima vez. Y esa costumbre dura más que el bug.
¿Por qué «Algo ha salido mal» no basta?
La solución más rápida es un toast: Algo ha salido mal. Inténtalo de nuevo. Falla por cuatro motivos. No nombra la causa, así que no se distingue una errata de una caída del servidor. Propone una acción que puede ser la equivocada: reintentar tres veces con una tarjeta rechazada da tres veces la misma respuesta. Desaparece a los pocos segundos, a menudo antes de que alguien lo lea. Y si no está en una live region, quien usa un lector de pantalla ni siquiera lo oye.
El arreglo empieza antes del texto. Cada fallo tiene una causa distinta, algo distinto que el usuario puede hacer y, por tanto, un sitio distinto en la pantalla.
¿Cuáles son las seis maneras en que falla una petición?
Conviene agrupar los fallos según lo que el usuario puede hacer a continuación. El código de estado es solo el punto de partida. Seis grupos cubren casi todas las peticiones de un producto SaaS.
- Dato rechazado (400, 422). El servidor ha descartado un valor y el usuario puede corregirlo. El mensaje va junto al campo, el resto de valores se queda donde está y el foco pasa al primer campo con error.
- Sesión o permisos (401, 403). El usuario cerró sesión en otra pestaña o perdió el acceso. Puede volver a entrar o pedir permiso. Se le pide que vuelva a entrar ahí mismo, en un diálogo, y luego se reenvía la petición para que el trabajo no se pierda.
- Conflicto o elemento desaparecido (404, 409, 412). Otra persona ha cambiado o borrado el registro. Antes de decidir, el usuario necesita ver qué ha cambiado. Se muestran las dos versiones o se dice con claridad que el elemento ya no existe y adónde ir.
- Demasiadas peticiones o servidor saturado (429, 503). El servidor pide al cliente que frene, a menudo con una cabecera
Retry-After. El usuario solo puede esperar. Se muestra cuánto, con una cuenta atrás, y se reintenta sin preguntar. - Error del servidor (500, 502). Algo ha fallado al otro lado. Se reintenta una vez de forma automática y, si vuelve a fallar, se muestra un código de referencia para enviar a soporte.
- Sin conexión o tiempo agotado. La petición no recibió respuesta y el usuario no sabe si llegó. La acción queda en cola, el mensaje dice que se enviará cuando vuelva la conexión y nada aparece como guardado hasta que el servidor lo confirme.
Lo que separa los seis grupos es una pregunta que guía todo el diseño: ¿la petición ha cambiado algo en el servidor? Con datos rechazados, permisos y conflictos, la respuesta es no. Con un timeout, la respuesta honesta es que el cliente no lo sabe, y ese es el caso que pide más cuidado.
¿Cómo se conserva el trabajo del usuario cuando falla una petición?
Las pautas de Nielsen Norman Group sobre mensajes de error lo resumen en pocas palabras: conservar lo que el usuario ha escrito. En la ruta de error eso se traduce en cuatro reglas.
- Un formulario nunca se vacía tras un error. Se vuelve a mostrar con los valores escritos, incluidos los que el servidor aceptó.
- Los textos largos (una descripción, un mensaje, un formulario de varios pasos) se guardan en el navegador mientras se escriben, para que una recarga o un cierre inesperado los recupere. Nuestras reglas para formularios largos tratan el autoguardado con más detalle.
- Cuando la sesión caduca, se vuelve a entrar desde un diálogo sobre la página. Redirigir a la página de inicio de sesión tira el formulario.
- Si la interfaz se actualizó de forma optimista (la fila apareció antes de la respuesta del servidor), el cambio se deshace a la vista y se explica por qué. Una fila que desaparece sin aviso parece un dato perdido.
¿Cuándo es seguro mostrar el botón Reintentar?
Un botón Reintentar promete que pulsarlo dos veces no hará lo mismo dos veces. En las lecturas ya es así. En las escrituras solo lo es si el servidor reconoce una repetición. La API de Stripe lo resuelve con una clave de idempotencia: el cliente envía una clave única con cada creación o modificación, Stripe guarda la primera respuesta asociada a esa clave y cualquier reintento con la misma clave recibe esa respuesta en lugar de un segundo cargo. Stripe conserva las claves al menos 24 horas. Los endpoints de tu producto necesitan el mismo patrón antes de que la interfaz ofrezca reintentar un pago, una invitación o cualquier acción que envíe un email.
Los reintentos automáticos también necesitan límites. La Builders' Library de Amazon describe los reintentos como «egoístas»: cuando un servicio falla porque está saturado, cada reintento añade carga y puede empeorar la caída. El patrón que recomienda es el backoff exponencial con tope y jitter: esperar más tras cada intento, parar en un máximo y añadir una parte aleatoria para que mil clientes no reintenten en el mismo segundo. Si el servidor envía Retry-After con un 429 o un 503, manda su número (la cabecera la define la RFC 9110 y el estado 429, la RFC 6585).
En la interfaz seguimos tres reglas: un reintento silencioso en una lectura, ninguno en una escritura sin clave de idempotencia y un estado visible para todo lo que dure más de un par de segundos.
¿Cómo se escribe un mensaje de error?
La rúbrica de evaluación de NN/g divide un buen mensaje en visibilidad, comunicación y eficiencia. En pantalla bastan dos frases: qué ha pasado y qué hacer ahora.
- La causa, con las palabras de quien lee. Tu banco ha rechazado la tarjeta dice a quién llamar. Error de pago 402, no.
- El siguiente paso, como botón. Usar otra tarjeta, Volver a entrar, Cargar la última versión. Un mensaje sin acción deja al usuario adivinando.
- Sin culpas. NN/g desaconseja palabras como invalid, illegal o incorrect, que en español serían «no válido», «no permitido» o «incorrecto». Esta fecha es anterior a la de inicio explica. Fecha no válida regaña.
- Un peso a la altura del daño. El error de un campo va bajo el campo. Un guardado fallido de toda la página merece un banner que se queda hasta que el usuario actúe. La página de error completa es para cuando no funciona nada, y aun así conserva la navegación para poder salir.
- Un código de referencia en los errores del servidor. Un código corto que se pueda pegar en un ticket convierte «no va» en una línea de log que alguien puede encontrar.
¿Cómo se hace accesible la ruta de error?
Un error marcado solo en rojo deja fuera a quien no distingue los colores y a quien no ve la pantalla. Las WCAG fijan el mínimo. El criterio 3.3.1 exige que un error detectado se identifique y se describa con texto. El criterio 3.3.3 exige una sugerencia para corregirlo cuando se conoce. El primero es de nivel A y el segundo de nivel AA: los dos entran en el nivel AA de las WCAG 2.1 que incorpora la norma EN 301 549, como contamos en el artículo sobre la European Accessibility Act.
En el marcado, eso significa:
aria-invalid="true"en el campo con error yaria-describedbyapuntando al mensaje, para que el lector de pantalla lea el mensaje junto al campo.- Una live region (
role="alert"para los fallos urgentes,aria-live="polite"para el resto) en los errores que aparecen sin recargar la página, como describe la referencia de MDN sobre el rol alert. - Un icono o una etiqueta junto al color, para que el estado se lea también en escala de grises.
- El foco en el primer campo con error, o en el banner, después de un envío fallido.
¿Cómo se ve la ruta de error en una sola pantalla?
Un caso ilustrativo: en una herramienta de facturación B2B, alguien edita una factura y pulsa Guardar. Esta es la misma pantalla en los seis fallos.
- El número de IVA está mal escrito (422). El campo pasa a su estado de error con Al número de IVA le falta el prefijo del país, por ejemplo ES o IT, el foco salta a él y el resto de campos sigue relleno.
- La sesión caducó hace una hora (401). Se abre un diálogo de acceso sobre la factura. Tras entrar, el guardado sale con la misma clave de idempotencia.
- Mientras tanto, una compañera ha cambiado el vencimiento (409). Un banner dice Anna ha movido el vencimiento al 30 de noviembre mientras editabas y ofrece Mantener mi cambio o Usar el suyo.
- La API ha llegado al límite (429, Retry-After: 20). El botón pasa a Guardando en 20 s y hace la cuenta atrás. No hace falta pulsar nada.
- El servidor responde 500. Un reintento automático con la misma clave. Si también falla, un banner dice No hemos podido guardar la factura. Tus cambios siguen aquí. con Reintentar y un código de referencia.
- El portátil pierde el wifi. La factura muestra Aún sin guardar. La guardamos en cuanto vuelvas a tener conexión. y el título de la pestaña lleva una marca hasta que el guardado llega.
Seis estados, un componente. En un design system son variantes del mismo formulario y del mismo banner, y por eso los dibujamos en el mismo archivo que el flujo principal, en lugar de dejarlos para un ticket después del lanzamiento. El mismo razonamiento sirve para la pantalla antes de que existan datos, que tratamos en diseño de estados vacíos.
Preguntas frecuentes
No como titular. Un 409 o un 503 no dice nada a la mayoría de los usuarios, y ponerlo delante esconde la frase que necesitan. Primero van la causa y el siguiente paso; después, el código de estado y un código de referencia en una línea más pequeña o en un desplegable de Detalles, donde los encuentran soporte y los usuarios técnicos. Las herramientas para desarrolladores y las consolas de API son la excepción: ahí el código de estado es el dato más útil de la pantalla, así que va a la vista.
Sí, para una acción en segundo plano que no bloquea nada y se puede reintentar desde el propio toast, como la sincronización fallida de una lista que el usuario no está editando. Tiene que quedarse en pantalla hasta que el usuario lo cierre: un mensaje que se desvanece a los cuatro segundos puede irse antes de que llegue a él quien lee despacio o usa un magnificador de pantalla. Va dentro de una live region para que los lectores de pantalla lo anuncien. Para un guardado fallido de algo que el usuario tiene delante, mejor un mensaje en línea o un banner junto al contenido.
En las lecturas, uno o dos intentos con backoff en unos dos segundos y luego un estado visible. En las escrituras, ninguno sin clave de idempotencia, porque un reintento podría crear un duplicado. Con clave, un reintento automático es una buena norma antes de preguntar al usuario. Cuando el servidor envía Retry-After, se espera ese tiempo y se muestra la cuenta atrás: reintentar antes añade carga a un servicio que ya ha dicho que está saturado.
Provocando cada fallo a propósito. Chrome DevTools pone el panel Network en Offline, limita la conexión y bloquea una sola URL de petición. Una capa de mocks como Mock Service Worker, o un flag de prueba en tu API, devuelve un 401, un 409, un 429 o un 500 cuando se le pide. Después se pasan todos los formularios y guardados por los seis fallos y se comprueban tres cosas cada vez: lo escrito sigue ahí, el mensaje indica un siguiente paso y el lector de pantalla lo anuncia.
Servicios relacionados
Artículos relacionados
Diseño
DiseñoBorde o sombra en la interfaz: cuándo usar cada uno y cuándo un fondo
Las sombras desaparecen con colores forzados y se pierden en modo oscuro, y el borde de un campo necesita 3:1. Cuándo separar con borde, sombra o fondo.
Diseño