Supabase no envía correos de confirmación: cómo arreglarlo
Por qué Supabase deja de enviar correos de confirmación o de recuperar contraseña (límites, SMTP propio, enlaces rotos) y cómo arreglar cada causa.
Read in English →
Lo más común es que Supabase no envíe los correos de confirmación o de recuperar contraseña porque el proyecto sigue usando el servicio de correo incluido, que solo entrega a los miembros de tu equipo en Supabase y permite 2 mensajes por hora. La solución es conectar tu propio proveedor SMTP (Resend, Postmark, Amazon SES, SendGrid, Brevo u otro) y después subir el límite de envíos. Si el correo sí llega pero el enlace falla, el problema está en la configuración de URL o en un escáner que abre el enlace antes que tu usuario.
A continuación revisamos cada causa en el orden en que conviene descartarla: dónde mirar y cómo comprobar que quedó resuelta.
¿Por qué a mí me llega y a mis usuarios no?
Porque el envío incluido solo entrega a direcciones que pertenecen al equipo de la organización del proyecto. La documentación de SMTP de Supabase indica que cualquier otra dirección falla con el error Email address not authorized. Cuando pruebas el registro con tu correo, funciona. Cuando se registra un cliente real, no sale nada.
La misma página aclara que ese servicio funciona "lo mejor posible", sin garantía de entrega, y que no está pensado para producción. Toda app con usuarios reales necesita su propio SMTP.
¿Por qué deja de enviar después de un par de pruebas?
El envío incluido permite 2 correos por hora para todo el proyecto (Supabase advierte que el número puede cambiar sin aviso). Cuentan todos: confirmación de registro, enlace mágico, recuperación de contraseña y cambio de correo. Haces dos registros de prueba y la tercera persona no recibe nada hasta que pase la hora.
Además, Supabase Auth tiene límites por usuario. Según la página de rate limits de Auth, por defecto hay una ventana de 60 segundos antes de que el mismo usuario pueda pedir otra confirmación, otro enlace mágico o otra recuperación de contraseña. Cuando se alcanza un límite, la API responde 429 Too Many Requests. Si tu frontend ignora ese error, el usuario ve "revisa tu correo" y nunca le llega nada.
¿Cómo configuro un SMTP propio?
- Elige un proveedor y verifica tu dominio. Te pedirá agregar registros DNS (SPF y DKIM, e idealmente DMARC) para el dominio desde el que vas a enviar. Si también mandas correos de marketing, usa un subdominio como
auth.tuapp.comomail.tuapp.compara que no compartan reputación. - Crea las credenciales SMTP en el proveedor: host, puerto (normalmente 587), usuario y contraseña.
- Cárgalas en Supabase. En la configuración de Authentication del panel, activa el SMTP personalizado y completa host, puerto, usuario, contraseña, un remitente como
no-reply@tuapp.comy un nombre de remitente. - Sube el límite de envíos. Al guardar el SMTP propio, Supabase aplica un límite inicial de 30 correos por hora, que puedes cambiar en la página de Rate Limits de Auth. Ajústalo a los registros que esperas, con margen para el día de lanzamiento.
- Prueba con una dirección que no sea de tu equipo, por ejemplo un Gmail personal y un Outlook del trabajo.
Si tu proveedor ofrece una API en lugar de SMTP, o quieres controlar por completo el contenido y el envío, Supabase también tiene un Send Email Auth Hook. Para la mayoría de las apps pequeñas, SMTP es lo más sencillo.
Los registros DNS son donde más fallan estas configuraciones. Si el correo sale pero cae en spam, revisa nuestra guía sobre SPF, DKIM y DMARC para los correos de tu app.
¿Está activada la opción "Confirm email"?
Revisa la configuración del proveedor Email dentro de Authentication. Si Confirm email está apagado, Supabase inicia la sesión del usuario de inmediato y no envía ninguna confirmación; a veces la herramienta de IA lo deja así durante el prototipo. Si está encendido, nadie puede entrar hasta hacer clic en el enlace, así que un envío roto bloquea todas las cuentas nuevas.
Otro detalle: si alguien vuelve a registrarse con un correo que ya pertenece a un usuario confirmado, Supabase no revela que la cuenta existe. Tu app puede mostrar "revisa tu correo", pero no se envía una confirmación nueva. A esas personas conviene ofrecerles recuperar la contraseña.
¿Por qué el enlace lleva a localhost o a otro sitio?
El enlace del correo se arma con la Site URL del proyecto y la URL de redirección que pasa tu código (por ejemplo emailRedirectTo en el registro o redirectTo en resetPasswordForEmail). Ambas se controlan en Authentication > URL Configuration.
- Si la Site URL sigue siendo
http://localhost:3000o una dirección de vista previa, los enlaces apuntan ahí. - Si tu código pasa una URL que no está en la lista de Redirect URLs, Supabase usa la Site URL en su lugar.
Pon tu dominio real en la Site URL y agrega todas las redirecciones válidas, incluidas las de vista previa si las necesitas. En el redirect de login de Lovable en tu dominio lo explicamos paso a paso.
¿Por qué el enlace dice "Token has expired or is invalid"?
Si el correo llega, el usuario hace clic enseguida y aun así ve ese error, la causa más común es la precarga de enlaces. La documentación de plantillas de correo de Supabase explica que algunos proveedores de correo tienen filtros de seguridad que abren los enlaces de los mensajes entrantes. Eso consume el enlace de un solo uso antes de que la persona lo toque, algo que puede pasar con buzones corporativos que revisan enlaces.
Hay dos soluciones documentadas:
- Enviar un código en lugar de un enlace. Usa
{{ .Token }}en la plantilla para incluir un código de 6 dígitos que el usuario escribe en tu app. - Enlazar a una página con un botón. Arma tu propio enlace con
{{ .TokenHash }}que abra una página de tu app y verifica el token solo cuando el usuario presione "Confirmar". El escáner carga la página, pero no presiona el botón.
Otras causas del mismo error: el usuario abrió un correo viejo después de pedir uno nuevo, o tu proveedor de correo reescribió los enlaces para medir clics. Supabase recomienda desactivar el seguimiento de clics en los correos de autenticación.
¿Cómo veo qué pasó realmente?
Abre los logs de Auth en el panel de Supabase y busca la hora del intento fallido. Normalmente verás una de tres cosas: un rechazo por límite, un error de SMTP (contraseña incorrecta, remitente sin verificar) o un envío exitoso. Después revisa el registro de actividad de tu proveedor SMTP, que muestra si el mensaje se entregó, rebotó o se marcó como spam. Con esos dos registros casi siempre encuentras el problema en pocos minutos.
Respuestas rápidas
¿Puedo subir el límite de 2 por hora sin SMTP propio? No. Ese límite del envío incluido no está pensado para subirse; configura un SMTP propio y ajusta el límite ahí.
¿Los correos de recuperar contraseña tienen el mismo problema? Sí. Recuperación, enlace mágico, invitación y cambio de correo usan el mismo envío y los mismos límites. Para el resto del flujo, mira cómo recuperar la contraseña de forma segura.
¿Qué proveedor SMTP elijo? Cualquier proveedor serio de correo transaccional sirve. Elige uno cuya verificación de dominio puedas completar y cuyo plan gratuito o inicial alcance para tu volumen.
¿Los demás correos de mi app deberían salir por Supabase? No. El SMTP de Supabase es para los correos de autenticación. Recibos y notificaciones conviene enviarlos desde tu backend; lo vemos en enviar correos desde una app de Lovable.
¿Sigue sin llegar?
La revisión gratuita de tu app te da una primera mirada desde afuera. Si el registro o el login está frenando a tus clientes, nuestra revisión de seguridad de Supabase cubre toda la configuración de Auth, y puedes contarnos qué estás viendo.


