Deprecating or changing how django.core.mail handles fail_silently

I’d like to move this forward to make room for EMAIL_PROVIDERS. From that lack of responses, I gather nobody has strong opinions one way or the other. Which isn’t surprising: I’m pretty sure fail_silently doesn’t show up much in production Django code.

Unless there’s further (human) input, I’ll open a ticket to deprecate fail_silently for everything except mail_admins() and mail_managers()—option 3 below.

I poked into fail_silently usage through GitHub code search, then asked three AIs for a broader perspective on how it’s used in projects they’ve seen. (I hoped their training data might supply the answer to my earlier question, “Is there some use case I’m missing?” The AI analyses seemed to align with patterns I had spotted in my GitHub search.)

My takeaways:

  • The overwhelming majority of django.core.mail calls use the default fail_silently=False. (It’s unusual to ignore email errors in production. This decision just doesn’t impact that much code.)
  • Many uses of fail_silently=True were likely copied from older tutorials or references, for no good reason. (Two AI’s referred to “cargo culting.”)
  • Where fail_silently=True is intentional, callers seem to have different expectations for which errors would be silenced. Many want “don’t crash this path” (ignore all errors), but others seem to be saying “don’t bother me with network glitches” and would want other errors to be loud.
  • The exception is mail_admins(): when it’s called with fail_silently=True (which is also rare), it’s in error handling paths that want to avoid cascading errors. Callers expect it to suppress all exceptions. (The same argument probably applies to mail_managers(), but that function isn’t widely used.)
  • All uses of fail_silently expect it to apply to that one send—nobody thinks of it as EmailBackend configuration.

I see three options:

  1. Make fail_silently ignore all Exceptions (broad try/catch in EmailMessage.send() as described in the first post in this thread; GPT and Claude both wanted to refine this to not ignore MemoryError or RecursionError)

  2. Deprecate fail_silently and remove it in Django 7.0. Callers would need to replace fail_silently=True with their own exception handling, forcing them to be explicit about which (if any) exceptions they want to ignore (second post in this thread)

  3. Hybrid approach: Keep fail_silently for mail_admins() and mail_managers() (ignoring all Exceptions), but deprecate and remove it for send_mail(), send_mass_mail() and EmailMessage.send().

I’ve tried to map the AIs’ opinions to our usual voting scale:

Mike (human) Claude 4.6 Opus Gemini 3.1 Pro GPT 5.3 Codex
Option 1 +0 +1 +0 +1
Option 2 -1 -1 -1 -1
Option 3 +1 -0 +1 -1

Gemini and I both feel option 3 is pragmatic for real-world use, and easy to explain and document. (I think GPT’s a little alarmist about the impact of removing it, so I’m discounting its -1 on option 3.)

Full chat transcripts: * django.core.mail fail_silently usage.md · GitHub. (The options were discussed in a different order from above: 1=A, 2=C, 3=B.)