Aller au contenu

Bases de la sécurité

Supabase "Email Rate Limit Exceeded" : deux limites, un code

Supabase "Email Rate Limit Exceeded" plafonne chaque e-mail de votre projet : 2 par heure avec l'expéditeur intégré. Ce qui compte, et comment le relever.

Vlad Tkachenko11 min de lecture
Une planche de timbres dont chaque timbre a déjà été arraché, à côté d'une pile d'enveloppes fermées sans rien dans leur coin.

En bref

  • Supabase "Email Rate Limit Exceeded" signifie que votre projet a envoyé cette heure-ci autant d'e-mails qu'il en a le droit. Avec l'expéditeur intégré, c'est 2 par heure, et chaque confirmation d'inscription, chaque lien magique et chaque réinitialisation de mot de passe compte.
  • Le même code, over_email_send_rate_limit, revient aussi avec "For security purposes, you can only request this after N seconds", une attente de 60 secondes pour une seule adresse. Seul le message distingue les deux.
  • Votre propre fournisseur SMTP lève le plafond horaire une fois que vous relevez aussi la limite sur la page Rate Limits, qui démarre à 30 par heure. L'attente de 60 secondes reste, et votre formulaire doit l'expliquer.

Vous testez votre formulaire d'inscription avant de partager l'application. Vous vous inscrivez avec votre propre adresse, puis avec vous+2@gmail.com, puis une fois de plus pour vérifier que l'e-mail de confirmation est bien présenté. L'une de ces tentatives s'arrête sur ceci :

AuthApiError: email rate limit exceeded

Supabase "Email Rate Limit Exceeded" signifie que votre projet a épuisé son quota d'e-mails pour l'heure. Supabase Auth, la partie de Supabase qui connecte les gens, a donc refusé d'en envoyer un autre. Avec le service d'e-mail qu'a tout projet au départ, ce quota est de deux e-mails par heure pour tout le projet.

Voici la partie qu'on comprend facilement de travers : le code d'erreur couvre deux limites différentes. La propre liste des codes d'erreur Auth de Supabase décrit over_email_send_rate_limit comme "Too many emails have been sent to this email address." C'est vrai pour l'une des deux. Le même code revient aussi quand tout le projet est à court, quel que soit le destinataire de l'e-mail, donc essayer une autre adresse ne change rien. Et le conseil habituel, "branchez votre propre SMTP", ne règle que la moitié du problème, parce que Supabase démarre un serveur d'e-mail fraîchement branché à 30 e-mails par heure.

Que signifie "Email rate limit exceeded" dans Supabase ?

Votre projet a envoyé cette heure-ci autant d'e-mails que Supabase Auth le permet, et le suivant a été refusé.

Imaginez le quota comme une planche de timbres. Supabase donne à chaque projet un nombre fixe de timbres par heure, et chaque e-mail envoyé par Supabase Auth en utilise un, quel que soit le type d'e-mail et quel que soit son destinataire :

  • le lien de confirmation après une inscription
  • un lien magique ou un code à usage unique pour se connecter
  • une réinitialisation de mot de passe
  • une invitation que vous envoyez depuis la page Users
  • la confirmation quand quelqu'un change son adresse e-mail

Quand la planche est vide, Supabase Auth répond avec HTTP 429, qui veut dire "trop de requêtes", le code over_email_send_rate_limit et le message email rate limit exceeded. Ces mots viennent du code même du serveur Supabase Auth.

Avec l'expéditeur intégré, le service d'e-mail avec lequel démarre un nouveau projet, la planche contient deux timbres par heure. C'est le chiffre de la page des limites de débit de Supabase quand nous l'avons lue le 20 octobre 2026, et le guide SMTP de Supabase précise qu'il "can change without notice". À deux par heure, une inscription et une réinitialisation de mot de passe font tout le quota de l'heure.

Chaque e-mail envoyé par Supabase Auth utilise un timbre de la même planche. Avec l'expéditeur intégré, la planche en contient deux par heure.

Si plus personne ne peut se connecter, ou si toute l'application est vide, le problème est ailleurs, et Supabase est-il en panne, ou est-ce votre app est le bon point de départ.

Deux limites partagent un même code d'erreur

Le message vous dit quelle limite vous avez atteinte. Le code est le même pour les deux :

Le messageCe qui est limitéCe qui est comptéLa valeur par défaut
email rate limit exceededTout le projetChaque e-mail envoyé par Supabase Auth, par heure2 par heure avec l'expéditeur intégré, 30 quand vous branchez le vôtre
For security purposes, you can only request this after N seconds.Une adresseLe même type d'e-mail, renvoyé à la même adresseUn toutes les 60 secondes

Les deux répondent HTTP 429 avec over_email_send_rate_limit. La liste des codes d'erreur Auth de Supabase vous demande d'identifier les erreurs par leur code et "not string matching on error messages". C'est juste pour le code de votre application, et cela laisse ici un trou : seul le message dit quelle limite vous avez atteinte. Lisez donc le message pour comprendre ce qui s'est passé, et laissez votre application réagir au code.

Si votre application dit seulement "une erreur est survenue", le message exact se trouve dans la réponse à la requête échouée, dans l'onglet Réseau des outils de développement de votre navigateur. Un code over_request_rate_limit est une troisième limite, sur les requêtes venant d'une même adresse IP, et la liste de Supabase indique qu'il peut signaler un bug de votre application qui en envoie trop.

Une planche vide et une attente de 60 secondes sont deux refus différents, et Supabase les signale avec le même code.

Pourquoi le message dit-il "you can only request this after 0 seconds" ?

Parce qu'il restait moins d'une seconde d'attente. La limite par adresse autorise un e-mail de chaque type vers la même adresse toutes les 60 secondes : une confirmation d'inscription, une réinitialisation de mot de passe, un lien magique ou un code. Redemandez plus tôt et Supabase Auth calcule le temps restant et l'écrit dans le message.

Il compte en secondes entières et laisse tomber le reste. La fonction du serveur Auth qui écrit ce message (errors.go) divise le temps restant par une seconde, donc 0,8 seconde s'affiche 0. Réessayez un instant plus tard et cela passe, tant que le plafond horaire du projet a encore un timbre.

Cette attente fait ce pour quoi elle existe. C'est elle qui empêche un bouton de renvoi, pressé vingt fois, d'envoyer vingt e-mails. Laissez-la à 60 secondes et laissez votre formulaire l'expliquer.

Le plafond horaire, et à qui il est destiné

L'expéditeur intégré sert à essayer Supabase, et Supabase le dit dans son guide SMTP. Le guide énumère ce à quoi le service est destiné : "Exploring and getting started with Supabase Auth", "Setting up and testing email templates with the members of the project's team" et "Building toy projects, demos or any non-mission-critical application". Il vient aussi avec "No SLA guarantee on message delivery or uptime".

Le même guide a une deuxième règle, et c'est elle qui décide qui voit quelle erreur. Tant que vous n'avez pas branché votre propre serveur d'e-mail, Supabase Auth "will refuse to deliver messages to addresses that are not part of the project's team". Un client qui s'inscrit avec sa propre adresse est refusé avant même qu'un timbre soit compté, avec un autre message :

Email address "customer@example.com" cannot be used as it is not authorized

C'est HTTP 400 avec le code email_address_not_authorized, et dans le code du serveur Auth cette vérification passe avant les deux limites. Si l'inscription marche quand vous l'essayez et échoue pour tous les autres, c'est la raison.

Avec l'expéditeur intégré, email rate limit exceeded tombe donc surtout sur vous et votre équipe, pendant les tests. Quand le serveur Auth vérifie si une adresse fait partie de votre équipe, il ignore tout ce qui se trouve entre un + et le @. Ainsi vous+test1@gmail.com et vous+test2@gmail.com comptent tous deux comme vous, et chaque inscription de test utilise l'un des deux mêmes timbres.

Comment relever la limite d'e-mails de Supabase ?

Branchez votre propre fournisseur d'e-mail, puis relevez la limite que Supabase lui applique. Ce sont deux étapes distinctes, et c'est la seconde qu'on oublie.

  1. Choisissez un service d'envoi et récupérez ses réglages SMTP. Le guide de Supabase cite Resend, AWS SES, Postmark, Twilio SendGrid, ZeptoMail et Brevo, et précise que tout service qui prend en charge SMTP fonctionnera. Il vous faut l'hôte, le port, un nom d'utilisateur et un mot de passe, plus une adresse d'expéditeur comme no-reply@votredomaine.fr.
  2. Activez le SMTP personnalisé dans les réglages Authentication de votre projet et saisissez ces informations. À partir de là, Supabase envoie à toutes les adresses.
  3. Relevez la limite d'e-mails sur la page Rate Limits, elle aussi sous Authentication. Le guide indique qu'un serveur fraîchement branché reçoit "a low rate-limit of 30 messages per hour" pour protéger sa réputation, et que c'est là que vous la changez. Réglez-la sur ce que votre fournisseur autorise et sur ce dont votre heure la plus chargée a besoin.

Trois autres points du même guide vont avec ce changement :

  • Configurez DKIM, DMARC et SPF pour votre domaine d'envoi, chez votre fournisseur. Supabase dit que cela "will significantly increase the deliverability of your messages".
  • Activez le CAPTCHA sur les inscriptions. Le guide cite les robots qui inscrivent des listes d'adresses comme "a common source of abuse", et chacune de ces inscriptions est un e-mail pris sur votre heure. Il appelle le CAPTCHA "the most effective way" de les arrêter.
  • Vérifiez que vos utilisateurs ne sont pas déconnectés. Selon le guide, des sessions courtes obligent "active users to sign in frequently, increasing the number of messages", et si vos utilisateurs se connectent par lien e-mail, chaque déconnexion inattendue coûte un timbre. Pourquoi les utilisateurs de Supabase sont déconnectés en explique les causes.

Pour les autres limites qu'un projet gratuit rencontre, voyez ce que comprend l'offre gratuite de Supabase.

Gérer l'erreur dans votre formulaire d'inscription

Interceptez-la par son code et dites à la personne quoi faire, en termes clairs. Le client JavaScript de Supabase met le code du serveur sur l'erreur qu'il renvoie, sous error.code, donc la vérification tient en une ligne :

const { error } = await supabase.auth.signUp({ email, password })

if (error?.code === 'over_email_send_rate_limit') {
  // afficher : "Nous n'avons pas pu envoyer votre e-mail pour l'instant. Réessayez dans une minute."
}

Demandez à votre outil, que ce soit Lovable, Bolt, v0, Cursor, Claude Code ou Replit, trois choses :

  • la même vérification sur chaque formulaire qui envoie un e-mail : inscription, "mot de passe oublié", connexion par lien e-mail et "renvoyer"
  • un message qui demande à la personne de réessayer sous peu, à la place de l'erreur brute ou d'un formulaire qui ne fait rien sans rien dire
  • le bouton de renvoi désactivé pendant 60 secondes après chaque envoi, pour que personne ne puisse le pousser dans l'attente par adresse

Évitez les nouvelles tentatives automatiques. Tant que la planche est vide, chaque tentative est refusée, et les requêtes d'inscription sont aussi limitées par adresse IP, à 30 toutes les 5 minutes par défaut. Une boucle de tentatives peut déclencher cette limite aussi, et celle-ci répond avec over_request_rate_limit.

Ce qu'il ne faut pas changer pendant que les inscriptions bloquent

La confirmation par e-mail, et l'endroit d'où partent les e-mails. Deux raccourcis font disparaître l'erreur et vous laissent en moins bonne posture.

Laissez la confirmation par e-mail activée. Désactiver "Confirm email" fait que les inscriptions n'envoient plus rien, donc l'erreur disparaît. Le guide SMTP de Supabase range "Do not disable email confirmations under pressure" parmi ses protections, parce que sans confirmation quelqu'un peut créer un compte au nom d'une autre personne.

Gardez les e-mails hors du navigateur. Demandez à un assistant "d'envoyer simplement la confirmation avec Resend" et il peut placer la clé d'API du fournisseur dans le code frontend de votre application, où chaque visiteur peut la lire et envoyer du courrier en votre nom. Envoyez les e-mails par les réglages SMTP de Supabase ou par une fonction côté serveur, jamais avec une clé dans la page. Si vous n'êtes pas sûr qu'aucune ne s'y est glissée, notre scan gratuit lit le code que votre application en ligne envoie à chaque visiteur et signale les clés secrètes qu'il y trouve. Il prend environ 20 secondes et ne demande pas de compte : scannez votre app.

Garder un œil sur l'application pendant que vous changez l'envoi des e-mails

Deux choses peuvent mal tourner pendant que vous recâblez l'envoi d'e-mails : une clé se retrouve dans le code de votre application, et un message disant "personne ne peut s'inscrire" vous lance à la recherche d'une panne.

Reeve Monitor continue de vérifier depuis l'extérieur :

  • si votre application répond, vérifié chaque minute, pour savoir tout de suite si une plainte sur l'inscription est une panne ou quelque chose de plus limité
  • la vérification de sécurité complète toutes les heures, sur trois applications au plus, y compris les clés secrètes dans le code que votre application envoie aux visiteurs
  • un message quand un résultat change, pour qu'une clé partie avec un déploiement ultérieur vous parvienne sans que vous alliez voir
  • un rapport mensuel, en langage clair, de ce qu'il a vu

Reeve Care garde une copie de votre base de données Supabase :

  • une copie chiffrée selon un calendrier, sur le stockage de Reeve dans l'UE, hors de votre compte Supabase
  • le schéma auth, où vit chaque compte qui a réussi à s'inscrire
  • chaque copie vérifiée avant de compter, en comptant les lignes de chaque table
  • vos fichiers envoyés aussi, dès que vous connectez un accès Storage
  • une restauration en un clic, précédée d'une copie de sécurité de l'état actuel
  • tout ce que fait Monitor

Que faire maintenant

Que faire

  • Lisez le message autant que le code : email rate limit exceeded est le plafond horaire du projet, et For security purposes… est l'attente de 60 secondes pour une adresse.
  • Si des clients voient Email address … cannot be used as it is not authorized, votre projet passe encore par l'expéditeur intégré de Supabase, qui n'écrit qu'à votre équipe.
  • Branchez votre propre fournisseur SMTP, puis relevez la limite d'e-mails sur la page Rate Limits, qui démarre à 30 par heure.
  • Configurez DKIM, DMARC et SPF chez votre fournisseur, et activez le CAPTCHA sur les inscriptions.
  • Faites vérifier over_email_send_rate_limit à chaque formulaire qui envoie un e-mail, afficher un message clair et bloquer le bouton de renvoi 60 secondes.
  • Gardez la confirmation par e-mail activée, et ne mettez jamais la clé d'un fournisseur d'e-mail dans votre frontend.

Commencez par le message dans la réponse échouée, parce qu'il vous dit laquelle des deux limites vous avez atteinte. Puis, une fois que les e-mails partent par votre propre fournisseur, scannez votre app pour vérifier qu'aucune clé n'a suivi.

FAQ

Que signifie "email rate limit exceeded" dans Supabase ?

Votre projet a envoyé cette heure-ci autant d'e-mails que Supabase Auth le permet, donc le suivant a été refusé. Le compte inclut chaque e-mail qu'Auth envoie, à qui que ce soit : confirmations d'inscription, liens magiques, réinitialisations de mot de passe et invitations. Avec l'expéditeur intégré, c'est 2 par heure. Avec votre propre fournisseur SMTP, vous fixez le chiffre vous-même.

Pourquoi le message dit-il que je ne peux redemander qu'après 0 seconde ?

Parce qu'il restait moins d'une seconde sur l'attente de 60 secondes. Supabase Auth compte le temps restant en secondes entières et laisse tomber le reste, donc la dernière seconde s'affiche comme 0. Réessayez un instant plus tard et l'e-mail part, tant que le plafond horaire a encore de la place.

Combien d'e-mails Supabase peut-il envoyer pour moi ?

Avec l'expéditeur intégré, 2 par heure pour tout le projet, et seulement aux personnes de votre équipe Supabase. Supabase précise que ce chiffre peut changer sans préavis. Avec votre propre fournisseur SMTP, il n'y a pas de chiffre fixe : Supabase démarre à 30 par heure et vous l'augmentez sur la page Rate Limits.

Ai-je besoin de mon propre fournisseur SMTP ?

Oui, dès que quelqu'un d'extérieur à votre équipe s'inscrit par e-mail. L'expéditeur intégré refuse les adresses qui ne sont pas dans votre équipe, et Supabase le décrit comme fait pour essayer, tester des modèles et faire des démos. Resend, AWS SES, Postmark, SendGrid, ZeptoMail et Brevo font partie des services que Supabase cite comme compatibles.

Comment éviter que cela casse mon formulaire d'inscription ?

Vérifiez le code de l'erreur avant que quoi que ce soit n'arrive à l'écran. Si c'est over_email_send_rate_limit, affichez un message clair qui demande de réessayer dans une minute, et gardez le bouton de renvoi désactivé 60 secondes après chaque envoi, pour que personne ne puisse le pousser dans l'attente.

Pourquoi mes clients reçoivent-ils "Email address not authorized" ?

Parce que votre projet envoie encore par l'expéditeur intégré de Supabase, qui ne livre qu'aux membres de votre organisation Supabase. Tous les autres sont refusés avec le code email_address_not_authorized. Brancher votre propre fournisseur SMTP règle le problème, et c'est le même changement qui lève le plafond horaire.

Écrit par

Vlad Tkachenko

Fondateur de Reeve

Je passe mes journées à examiner des applications créées avec Lovable, Bolt, v0, Cursor et Replit, et la courte liste d'erreurs qui y reviennent sans cesse.

En savoir plus sur l'auteur

À lire ensuite

Tous les articles

Sauvegardez votre base Supabase avant la prochaine modification

Reeve en garde une copie chiffrée à intervalles réguliers et la restaure pour vous en cas de problème.

Voir les sauvegardes Supabase

Vérification externe automatisée, pas un audit complet. L'absence de problème n'est pas une garantie de sécurité.