django_mailgun.MailgunBackend无法发送Django错误邮件,遇静默400响应求助
django_mailgun.MailgunBackend Silent 400 Failures for Django Error Emails Hey there, let's dig into why your Mailgun backend is failing silently with a 400 response and not sending those crucial Django error emails. I’ve run into this exact issue before, so here are the most likely culprits and fixes:
Common Causes & Solutions
1. Invalid or Misconfigured Mailgun Credentials
A 400 response from Mailgun almost always starts with wrong API keys or domain settings. Double-check:
- Your
MAILGUN_API_KEYin Django settings—make sure it includes the fullkey-prefix (e.g.,key-abc123xyz), not just the random string part. - Your
MAILGUN_SENDER_DOMAINmatches exactly the domain you’ve verified in your Mailgun dashboard. If you’re using a sandbox domain for testing, remember it only works with pre-verified recipient emails. - Ensure
DEFAULT_FROM_EMAILin Django points to an address on your verified Mailgun domain (e.g.,django-errors@your-domain.com), not a random Gmail/Outlook address.
2. Silent Error Suppression in the Backend Code
The default django_mailgun.py might be swallowing errors instead of raising them, which is why you didn’t see the 400 until you modified the code. Here’s how to fix that:
Open the backend file and modify the send method to raise an exception when the API call fails. For example:
def send_messages(self, messages): # ... existing code ... response = requests.post( self.api_url, auth=("api", self.api_key), data=payload, ) # Add this block to stop silent failures if not response.ok: raise RuntimeError( f"Mailgun API request failed with status {response.status_code}: {response.text}" ) # ... rest of the code ...
This way, Django will log the full error details instead of failing silently, making it way easier to debug.
3. Invalid Recipient or Sender Addresses
Mailgun enforces strict rules on sender/recipient addresses:
- If using a sandbox domain, recipients must be explicitly verified in your Mailgun account (check the "Authorized Recipients" section in your dashboard).
- Sender addresses must belong to your verified Mailgun domain—no random addresses allowed.
- Ensure there are no typos in recipient emails (e.g., missing
.comor extra spaces).
4. Missing Required Email Fields
Mailgun’s API requires certain fields to send an email: from, to, subject, and either text or html. Sometimes Django’s error emails might be missing one of these (e.g., an empty subject due to a weird error scenario). To test this, manually trigger an error email with a simple view:
from django.core.mail import send_mail from django.http import HttpResponse def test_error_email(request): send_mail( "Test Error Subject", "This is a test error message", "django-errors@your-domain.com", ["your-email@example.com"], fail_silently=False, ) return HttpResponse("Test email sent")
If this throws an error, you’ll get the exact issue from the raised exception.
5. Unverified Mailgun Domain
If your domain isn’t fully verified in Mailgun (you skipped the DNS TXT/CNAME records setup), Mailgun will reject all send requests with a 400. Head to your Mailgun dashboard, check the domain status, and make sure all DNS records are properly propagated.
Quick Test to Isolate the Issue
First, rule out Mailgun API issues entirely by running this curl command in your terminal:
curl -s --user 'api:YOUR_MAILGUN_API_KEY' \ https://api.mailgun.net/v3/YOUR_MAILGUN_DOMAIN/messages \ -F from='Django Errors <django-errors@YOUR_MAILGUN_DOMAIN>' \ -F to='your-personal-email@example.com' \ -F subject='Test API Email' \ -F text='This is a direct test from the Mailgun API.'
If this returns a 400, the problem is with your Mailgun account/domain setup, not the Django backend. If it works, the issue is in your Django code or settings.
内容的提问来源于stack exchange,提问作者Kostyantyn

