symfony: Unable to send an email: to parameter is missing (code 400).
Symfony version(s) affected
v6.4.4
Description
Sending emails no longer works without any adjustments. I retrieve the error Unable to send an email: to parameter is missing (code 400). Other having this problem?
How to reproduce
Sending e-mails via Laravel:
Mail::to('test@example.com') ->send(new OrderCreated($order));
Possible Solution
No response
Additional Context
No response
About this issue
- Original URL
- State: closed
- Created 3 months ago
- Comments: 22 (10 by maintainers)
Anyone looking for a Laravel workaround, you can add this to your mailgun config
I created a local HTTP/2 server with Deno to debug the request further. My findings:
curl
seems to ignore theTransfer-Encoding: chunked
header in HTTP/2 mode.$body->bodyToIterable()
.This is the debug output from the HTTP/2 server. Note how the form data is mangled and missing the first entry (
from
), resulting in theUnable to send an email: from parameter is missing (code 400)
error.Why did this issue arise suddenly? My guess would be that Mailgun just enabled HTTP/2 for their API endpoints. But I have no way to verify that.
So, the short-term solution would be forcing HTTP/1.1 requests for
MailgunApiTransport
. The long-term solution means looking into the way that Symfony uses content streaming for HTTP/2 requests viaCurlHttpClient
, which unfortunately is above my paygrade.I won’t be able to create a pull request today due to time constraints, but I’ll open one tomorrow if necessary.
In a follow-up to @hdimitrov1 for Laravel users - if you’ve got an app that’s been upgraded from earlier versions of laravel, pop the
client
key onto the base array of config/mail.php:Same issue here. Started from April, 4th.
The fix should appear in the next official release. For now you can either use one of the workarounds or configure
preferred-install
in your project.I found a better workaround that does not disable mail body streaming:
https://github.com/symfony/symfony/blob/524c7038065b65b91cce043e7eff31df901b71c8/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php#L63-L67
Set the HTTP version to
1.1
by adding the following option:So it seems the issue only occurs when the request is made with HTTP2.
I have been experiencing this problem since yesterday. But I’m not sure why it happened, if we haven’t updated dependencies and PHP version.
Turns out I was wrong and @eswinfen was onto something with the
bodyToIterable()
method. The request body sent to Mailgun seems to be empty.https://github.com/symfony/symfony/blob/524c7038065b65b91cce043e7eff31df901b71c8/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php#L66
Replacing
$body->bodyToIterable()
with$body->bodyToString()
resolves the issue and might be a temporary workaround. Just note that this will write the whole mail body to memory (including attachments!).So further debugging revealed that Symfony does create a valid looking request with all required headers and a chunked body. I wonder if the chunked transfer encoding might be borked, either on the client or server side.
@eswinfen I don’t think the
bodyToIterable()
method is the problem. It returns a generator that you can use like this:I replicated the Mailgun API request by copying the headers and body created by
MailgunApiTransport
to Insonmia and the request was successful. So the issue seems to be somewhere in the networking layer.I’m using PHP
8.3.4
btw.