Wade Shuler Wade Shuler - 1 year ago 58
Perl Question

Perl MIME::Lite nested boundaries

I am working on a server that is missing MANY Perl libraries, so I am left with using MIME::Lite. Yes, I should be using something else, but it is not within my control.

Overall, the email package needs to be "multipart/mixed". It will have the plain text version, html version, and an attachment. The issue is, it shows BOTH the plain text and html version in the email body.

I would like to still support "multipart/alternative" so it shows EITHER plain text or html. However, since I need an attachment, the whole email should be "multipart/mixed" with an inner boundary section with "multipart/alternative" for text/html versions.

I though I had it working, but it drops off the attachment due to the whole email package was "multipart/alternative". Inspecting some emails in my inbox, and I noticed you can have "mixed" first, then inside have "alternative". Like a div in a div :)

Here is my current code snip (please look for my comments defining the boundary):

my $type = 'multipart/mixed';

sub sendMail {
my($from, $to, $subject, $messageHtml, $messageText, $type, %attachment) = @_;

my $msg = MIME::Lite->new(
From => $from,
To => $to,
Subject => $subject,
Type => $type, # multipart/mixed

# -- start new boundary and multipart/alternative
if ( $messageText ne '' ) {
Type => 'text/plain; charset=UTF-8',
Encoding => 'quoted-printable',
Data => $messageText,

if ( $messageHtml ne '' ) {
Type => 'text/html; charset=UTF-8',
Encoding => 'quoted-printable',
Data => $messageHtml,
# -- end new boundary

if ( %attachment ) {
Type => $attachment{"type"},
Encoding => 'base64',
Path => $attachment{"path"},
Filename => $attachment{"filename"},
Disposition => 'attachment'

if ($debugmode) {
my $result = '';
print $result;

if ($msg->send) {
return 1;

return 0;

I would modify the code to check if both html and plain text were passed. I am well aware, that I don't need alternative if only 1 of them are used.

Again, I need the plain text and html sections, to be inside their own boundary as "multipart/alternative"

Answer Source

You have to first create the message as multipart/mixed. Inside this message you need to create an inner part as multipart/alternative. Onto this inner part you should attach the HTML and text parts. And the attachment should be added to the outer (mixed) part. This could be achieved with code like this:

use strict;
use warnings;
use MIME::Lite;

# main message is multipart/mixed
my $msg = MIME::Lite->new(
    From    => 'me@example.com',
    To      => 'you@example.com',
    Subject => 'some test message',
    Type    => 'multipart/mixed'

# inner part as multipart/alternative to include both HTML and text
my $alternative = $msg->attach(
    Type => 'multipart/alternative',
    Type => 'text/plain',
    Data => 'some TEXT here'
    Type => 'text/html',
    Data => '<b>some HTML here</b>'

# attached image goes to main message
    Type => 'image/gif',
    Data => 'GIF89a....'

print $msg->as_string;