I’m not sure, here’s what ChatGPT suggests:
Thanks for the detailed writeup — you’ve already covered a ton of ground, so kudos for narrowing it down this far. Since test emails and raw Laravel emails send fine, but actual Invoice Ninja emails don’t get delivered, it sounds like the problem may lie somewhere in how Invoice Ninja constructs or queues the messages, even if Laravel/Mail is working fine.
Here are some targeted ideas to investigate further:
1. Check Mail Headers / Content Differences
If you have access to the raw headers of test emails that work (from Mail::raw()
or the test email in the UI), compare them to those generated by actual Invoice Ninja emails (you might be able to log or intercept them using something like Mailtrap or Mailhog).
You’re looking for differences like:
- Missing
From
, Reply-To
, or Message-ID
- Suspicious HTML content or malformed headers
- Bounce-inducing phrases in subject or body
2. Try Switching to Log Mail Driver
Temporarily set MAIL_MAILER=log
in .env
and trigger an invoice email. Then check storage/logs/laravel.log
to inspect exactly what the email contains — this will help confirm if it’s being built as expected.
3. Look for Suppressed Messages
Some SMTP providers (like Amazon SES, Mailgun, or even your hosting provider) may silently drop certain messages if they think they’re spammy or repetitive — even if the SMTP transaction is successful.
If you’re using a mail provider:
- Check their suppression list or dashboard
- Check bounce/complaint feedback settings
- Look for any throttling or reputation flags
4. Try Changing the Email Content
Send a dummy invoice to yourself with a simplified subject and body, like “Test Invoice” and a basic line of text. This will help determine if the issue is content-related (eg. too many links, spammy phrases, large attachments, or problematic HTML).
5. Use a Mail Interceptor Locally
Tools like:
These let you see exactly what Invoice Ninja is generating, which helps isolate whether it’s an email construction problem or something downstream.
6. Double-check .env
vs UI Email Settings
Sometimes .env
settings (like MAIL_FROM_ADDRESS
or MAIL_FROM_NAME
) can override or conflict with the admin panel settings. Try clearing config cache just in case:
php artisan config:clear
php artisan cache:clear
php artisan optimize:clear
And restart PHP-FPM or your app container afterwards if needed.
7. Queue vs Sync – double-check behavior
Even though you’re using QUEUE_CONNECTION=sync
, Invoice Ninja might still dispatch certain jobs that Laravel handles asynchronously. Try manually triggering an invoice email and watching logs in real-time (tail -f storage/logs/laravel.log
) to catch anything subtle.
8. Try Running a Failing Example via Tinker
You could simulate the same invoice email through php artisan tinker
to see if anything pops:
use App\Models\Invoice;
use App\Jobs\Util\SendInvoiceEmail;
$invoice = Invoice::first();
SendInvoiceEmail::dispatchNow($invoice);
(or whatever the appropriate job/class is for your version)
If you want, I can help you test a few headers or even simulate the output of an invoice email to inspect for common spam triggers.
Let me know what mail provider or SMTP host you’re using too — that could help point to specific filters or suppression behaviors.