Bug Description
When configuring SMTP email settings in self-hosted Plane instances using Brevo (formerly Sendinblue) as the SMTP provider, the email credentials test always fails with a 400 error. The root cause is an SSL hostname mismatch between the DNS name (smtp-relay.brevo.com) and the server certificate (smtp-relay-offshore-southamerica-east-v2.sendinblue.com).
Steps to Reproduce
- Deploy a self-hosted Plane instance
- Navigate to God Mode → Email → SMTP Settings
- Configure with Brevo SMTP:
- Host: smtp-relay.brevo.com
- Port: 587
- Username: {Brevo_smtp_key_id}@smtp-brevo.com
- Password: {Brevo_SMTP_key}
- Email security: TLS
- Click "Send test email"
- Observe: Returns 400 error with no detailed message
Technical Analysis
The issue occurs in Django's SMTPEmailBackend.ssl_context property (django/core/mail/backends/smtp.py). When using STARTTLS (port 587) or SSL (port 465), Django creates a default SSL context with hostname verification enabled by default. Brevo's load-balanced SMTP infrastructure presents a certificate for a regional hostname that differs from the DNS-resolvable hostname, causing Python's SSL stack to reject the connection with:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'smtp-relay.brevo.com'.
This is not a misconfiguration — Brevo explicitly supports connecting via smtp-relay.brevo.com as documented, but the certificate is issued for the underlying regional server.
Suggested Fix
Modify the ssl_context property in django/core/mail/backends/smtp.py to provide an option to disable hostname verification for SMTP servers that use certificates from a shared infrastructure. Alternatively, add a configuration flag like EMAIL_SSL_HOSTNAME_VERIFY that defaults to True but can be set to False for providers like Brevo.
Environment
- Plane version: stable (v1.3.0+)
- Deployment method: Docker Compose
- SMTP Provider: Brevo (Sendinblue)
- Python version: 3.12
Bug Description
When configuring SMTP email settings in self-hosted Plane instances using Brevo (formerly Sendinblue) as the SMTP provider, the email credentials test always fails with a 400 error. The root cause is an SSL hostname mismatch between the DNS name (smtp-relay.brevo.com) and the server certificate (smtp-relay-offshore-southamerica-east-v2.sendinblue.com).
Steps to Reproduce
Technical Analysis
The issue occurs in Django's
SMTPEmailBackend.ssl_contextproperty (django/core/mail/backends/smtp.py). When using STARTTLS (port 587) or SSL (port 465), Django creates a default SSL context withhostname verificationenabled by default. Brevo's load-balanced SMTP infrastructure presents a certificate for a regional hostname that differs from the DNS-resolvable hostname, causing Python's SSL stack to reject the connection with:This is not a misconfiguration — Brevo explicitly supports connecting via
smtp-relay.brevo.comas documented, but the certificate is issued for the underlying regional server.Suggested Fix
Modify the
ssl_contextproperty indjango/core/mail/backends/smtp.pyto provide an option to disable hostname verification for SMTP servers that use certificates from a shared infrastructure. Alternatively, add a configuration flag likeEMAIL_SSL_HOSTNAME_VERIFYthat defaults toTruebut can be set toFalsefor providers like Brevo.Environment