How to include file attachments when sending emails through Mailgun in Laravel

I’m working on a Laravel app and need to send emails with file attachments using Mailgun API. The basic email sending works fine, but when I try to attach files, something goes wrong. Instead of getting my original PDF and image files, the email arrives with a weird file called “something.bin”.

class EmailNotification extends Mailable {
    use Queueable, SerializesModels;

    public function __construct($sender, $recipient, $title, $fileList) {
        if (strpos($recipient, 'test.com') !== false) {
            return;
        }

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);

        curl_setopt($curl, CURLOPT_URL, 'https://api.eu.mailgun.net/v3/'.config('app.mailgun_domain').'/messages');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POST, 1);

        $filePath = public_path() . '../storage/app/' . $fileList[0];

        $data = array(
            'from' => $sender,
            'to' => $recipient,
            'subject' => $title,
            'text' => 'message content',
            'attachment' => $filePath,
        );
        
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_USERPWD, 'api' . ':' . config('app.mailgun_secret'));

        $response = curl_exec($curl);
        curl_close($curl);
    }
}

The $fileList array contains the complete paths to all files I want to attach. What’s the correct way to handle file attachments with Mailgun API? Why are my PDFs and images showing up as bin files?

File attachments in email workflows are a nightmare, especially with cURL syntax and multipart encoding. I’ve been there way too many times.

Sure, the CURLFile approach works, but you’re building a complex email pipeline from scratch. Every tweak to attachment handling, provider changes, or template updates means more cURL debugging.

Automating the entire email workflow kills these headaches. Skip wrestling with Mailgun’s API in your Laravel code - set up proper automation that handles file attachments seamlessly.

Good automation platforms let you create workflows that receive email data and files, format everything for Mailgun (or whatever provider), and send it out. No more multipart encoding or CURLFile headaches. The platform handles the technical stuff while you focus on your app.

Your Laravel app just triggers the workflow with email details and file paths. The automation reads files, encodes them properly, and delivers through Mailgun without the bin file mess.

Bonus: switching email providers or adding preprocessing steps? Just update the workflow instead of refactoring Laravel code.

Latenode handles this email automation really well and solves all those attachment encoding issues: https://latenode.com

Had this exact problem a few months ago. You’re mixing cURL approaches wrong. For Mailgun file attachments, you can’t just throw file paths into CURLOPT_POSTFIELDS - you need curl_file_create() or CURLFile class to build proper multipart form data. But honestly? Skip the cURL headache entirely. Use Laravel’s HTTP client or Guzzle instead - they handle multipart uploads way better. That bin file mess happens because Mailgun gets the file path as a string instead of actual file content. I switched to Laravel’s Http facade with the ‘multipart’ option and boom - all attachment issues gone. Way cleaner than raw cURL and works with any file type without encoding drama.

The problem is Mailgun requires proper multipart/form-data encoding for attachments. You’re currently passing the file path as a string instead of the actual file data. Change ‘attachment’ => $filePath to ‘attachment’ => new CURLFile($filePath). Since your $fileList contains multiple files, be sure to loop through all of them and attach each file accordingly. Also, include curl_setopt($curl, CURLOPT_HTTPHEADER, array(‘Content-Type: multipart/form-data’)) for proper encoding. The .bin extension appears because the API receives raw string data instead of correctly formatted file content. Ensure your file paths are absolute and that the files exist before creating CURLFile objects to avoid further errors.

hey ryan, you’re not using the right format for file attachments. use new CURLFile($filePath) instead of just the string path. this’ll fix the issue with those .bin files! good luck!

mailgun’s api is finicky with files - add curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true) and use CURLFile. double-check your file paths exist first. that binary garbage usually means mailgun can’t read the file.