Pourquoi la validation email est plus complexe qu’il n’y paraît
“Valider un email” semble trivial. En pratique, c’est un problème à plusieurs dimensions avec des compromis non triviaux entre précision, latence, UX et complexité d’implémentation.
Une adresse email est “valide” selon quatre critères distincts :
- Syntaxe correcte : respecte la RFC 5322
- Domaine joignable : possède des enregistrements MX actifs
- Boîte existante : le serveur accepte des emails pour cette adresse précise
- Adresse légitime : n’est pas temporaire, jetable ou frauduleuse
La plupart des implémentations ne couvrent que les critères 1 et 2. Les critères 3 et 4 nécessitent des approches différentes.
Méthode 1 : Validation regex (syntaxe)
Comment ça fonctionne
Une expression régulière vérifie que l’adresse respecte une structure de base : présence d’un @, d’un domaine, d’un TLD. Par exemple :
// Regex basique (acceptable pour la plupart des cas)const basicEmailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
// Regex stricte conforme RFC 5322 (souvent trop restrictive)const rfcEmailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;Ce que ça détecte
- ✅ Adresses sans
@(jean.dupont.fr) - ✅ Adresses sans domaine (
jean@) - ✅ Adresses avec espaces (
jean [email protected]) - ✅ Caractères invalides manifestes
Ce que ça ne détecte pas
- ❌ Domaines inexistants (
[email protected]) - ❌ Adresses jetables (
[email protected]) - ❌ Boîtes inexistantes (
[email protected]) - ❌ Catch-all
Cas d’usage recommandé
Obligatoire pour tout formulaire web, mais insuffisant seul. Utilisez comme première ligne de défense avant toute vérification plus avancée.
Latence
0 ms (côté client). Aucune dépendance réseau.
Méthode 2 : Vérification DNS/MX
Comment ça fonctionne
Une requête DNS récupère les enregistrements MX du domaine. Si aucun enregistrement MX n’est trouvé, le domaine ne peut pas recevoir d’emails.
import dns.resolver
def has_valid_mx(domain: str) -> bool: try: answers = dns.resolver.resolve(domain, 'MX') return len(answers) > 0 except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): return FalseOn peut aller plus loin en récupérant également les enregistrements SPF et DMARC :
def get_email_security(domain: str) -> dict: result = {'has_mx': False, 'has_spf': False, 'has_dmarc': False}
try: result['has_mx'] = bool(dns.resolver.resolve(domain, 'MX')) except Exception: pass
try: txt_records = dns.resolver.resolve(domain, 'TXT') for record in txt_records: text = record.to_text() if 'v=spf1' in text: result['has_spf'] = True except Exception: pass
try: dmarc = dns.resolver.resolve(f'_dmarc.{domain}', 'TXT') result['has_dmarc'] = bool(dmarc) except Exception: pass
return resultCe que ça détecte
- ✅ Domaines inexistants (NXDOMAIN)
- ✅ Domaines sans MX (ne peuvent pas recevoir d’emails)
- ✅ Absences de SPF/DMARC (signal de risque)
Ce que ça ne détecte pas
- ❌ Adresses spécifiques inexistantes sur un domaine valide
- ❌ Adresses jetables (Yopmail a des MX parfaitement valides)
- ❌ Catch-all (le domaine a des MX, mais toutes les adresses acceptées)
Cas d’usage recommandé
Très efficace pour les campagnes emailing et imports de liste. Exécuté côté serveur avant/pendant l’import. Détecte rapidement les “faux domaines” et réduit les hard bounces de manière significative.
Latence
20–200 ms (requête réseau, TTL DNS variable). Acceptable côté serveur, à éviter en validation temps réel côté client.
Méthode 3 : Vérification SMTP
Comment ça fonctionne
La vérification SMTP simule l’envoi d’un email jusqu’au point de vérification du destinataire, sans envoyer de message réel :
import smtplibimport dns.resolver
def verify_smtp(email: str) -> bool: domain = email.split('@')[1]
# 1. Récupérer le MX mx_records = dns.resolver.resolve(domain, 'MX') mx_host = str(sorted(mx_records, key=lambda r: r.preference)[0].exchange)
# 2. Connexion SMTP with smtplib.SMTP(timeout=10) as smtp: smtp.connect(mx_host) smtp.helo('verify.example.com') # Votre domaine d'envoi code, message = smtp.rcpt(email) # 250 = accepté, 550 = rejeté, 421 = temporaire return code == 250Ce que ça détecte
- ✅ Boîtes de réception inexistantes (si le serveur répond honnêtement)
- ✅ Adresses qui ont été désactivées (ex-employés)
Limites importantes
- ❌ Domaines catch-all : répondent
250 OKà tout, qu’importe l’adresse - ❌ Serveurs qui bloquent les vérifications : Gmail, Outlook, Yahoo refusent ce type de requête — vous obtenez systématiquement
252(“cannot verify but will deliver”) - ❌ Greylisting : certains serveurs retardent la réponse pour les nouveaux expéditeurs
- ❌ Adresses honeypot : des adresses existent techniquement mais sont des pièges antispam
- ❌ Impact sur la réputation : des requêtes SMTP répétées depuis votre IP peuvent déclencher des défenses antispam
Cas d’usage recommandé
Utile pour les bases B2B de taille modérée, après vérification MX. À éviter pour les grandes bases (> 100 000 adresses) sans infrastructure dédiée. Inefficace pour les adresses Gmail, Yahoo, Outlook.
Latence
500 ms – 10 s selon le serveur. Incompatible avec la validation en temps réel côté client.
Méthode 4 : Score de risque (approche API)
Comment ça fonctionne
Cette approche combine les méthodes précédentes avec une couche supplémentaire d’intelligence : blacklist de domaines, fingerprinting DNS, âge du domaine, patterns comportementaux.
-H "Authorization: Bearer sv_votre_cle"{ "is_risky": true, "risk_score": 100, "reason": "disposable", "is_free_provider": false, "is_corporate_email": false, "did_you_mean": null, "is_alias_email": false, "mx_provider_label": "Yopmail", "deliverability_score": 0}Ce que ça détecte
- ✅ Adresses jetables connues (blacklist de 500 000+ domaines)
- ✅ Nouveaux domaines jetables (fingerprinting DNS)
- ✅ Adresses catch-all
- ✅ Domaines sans MX
- ✅ Adresses mal formatées
- ✅ Patterns de risque (domaine récent, absence auth email…)
Limites
- ❌ Boîtes individuelles inexistantes sur domaines légitimes (Gmail, entreprises non catch-all)
- ❌ Adresses invalides mais sur domaines sains (
[email protected])
Cas d’usage recommandé
Idéal pour la validation temps réel dans les formulaires web, inscriptions, checkout. Couvre les 4 principales menaces (format, domaine, jetable, risque) en un seul appel.
Latence
Très faible — hébergé en France, optimisé pour la validation temps réel dans les formulaires. Compatible avec une intégration directe sans proxy intermédiaire.
Comparaison synthétique
| Critère | Regex | DNS/MX | SMTP | API/Score |
|---|---|---|---|---|
| Syntaxe invalide | ✅ | ✅ | ✅ | ✅ |
| Domaine inexistant | ❌ | ✅ | ✅ | ✅ |
| Adresse inexistante | ❌ | ❌ | ✅* | ❌ |
| Email jetable | ❌ | ❌ | ❌ | ✅ |
| Catch-all | ❌ | ❌ | ❌ | ✅ |
| Latence | 0 ms | 20–200 ms | 500 ms–10 s | Très faible (EU) |
| Côté client | ✅ | ❌ | ❌ | Via proxy |
| Sans compte tiers | ✅ | ✅ | ⚠️ | ❌ |
*SMTP fonctionne uniquement si le serveur répond honnêtement (pas catch-all, pas de blocage).
La bonne combinaison selon votre cas
Formulaire web (SaaS, e-commerce, newsletter) → Regex côté client + API score côté serveur à la soumission
Import de liste B2B → Regex + DNS/MX + API score en batch (pas de SMTP) — voir notre protocole complet de nettoyage de liste B2B
Validation d’une base existante (campagne email) → DNS/MX + API score + SMTP optionnel sur segment B2B hors Gmail/Yahoo
Validation stricte (documents officiels, vérification identité) → SMTP + confirmation par email (envoi d’un code de vérification) — la seule méthode 100 % fiable
Pour aller plus loin sur le fingerprinting DNS qui complète ces méthodes, consultez notre article sur le fingerprinting MX et la détection en temps réel des domaines jetables. Vous pouvez tester les différentes méthodes sur notre checker en ligne, ou implémenter directement en consultant les guides d’intégration dans la documentation.