New guide: how to warm up a dedicated IP without hurting your reputation. Read now →
Log in
MigoSMTP
SMTP and APIUpdated 17 Oct 2026

MIME in Email Explained: Attachments, Multipart Messages, Content Types and Encoding

MIME is the standard that lets email carry attachments, HTML, inline images and text in any language. This guide explains the key headers, the multipart types, a worked example of a message with text, HTML and a PDF, base64 encoding and why attachments grow, inline images, and the common problems and fixes.

MO
Written by Mateus Oliveira
Senior SMTP and MTA Engineer
Reviewed by Sana Qureshi
  • Published13 Oct 2026
  • Read time7 min
  • Length1,368 words
Share this guide

MIME, short for Multipurpose Internet Mail Extensions, is the standard that lets email carry more than plain text. Attachments, HTML bodies, inline images, text in any language and messages that contain other messages are all built with MIME. If you have ever sent a PDF, an HTML newsletter or an email with both HTML and plain-text versions, you have used it. This guide explains how a MIME email is put together, what the content types mean, how attachments and inline images work, and the mistakes that cause garbled text or missing attachments.

Headersdescribe the content type, encoding and parts
Partsa message can hold several parts, such as text, HTML and files
Encodingbinary data is converted to text so that mail systems can carry it

Why MIME exists

The original email format, defined in RFC 822 and now in RFC 5322, handled only plain 7-bit ASCII text. That was enough in the early days, and not enough for attachments, accents, non-Latin scripts or rich formatting. MIME, introduced in the 1990s and defined in RFC 2045 to RFC 2049, added a way to say what a message contains and how it is encoded, without changing the way mail servers carry it. This is why modern email still works across systems of very different ages.

The key MIME headers

HeaderPurposeExample
MIME-VersionDeclares that the message uses MIMEMIME-Version: 1.0
Content-TypeThe type of content, and for multi-part messages, the boundary that separates the partsContent-Type: text/html; charset=UTF-8
Content-Transfer-EncodingHow the content is encoded for transportContent-Transfer-Encoding: base64
Content-DispositionWhether a part is shown inline or is an attachment, and the file nameContent-Disposition: attachment; filename="invoice.pdf"
Content-IDAn identifier that lets HTML refer to an inline part, such as an imageContent-ID: <logo123>

Content types you will meet

  • text/plain is plain text. text/html is an HTML body.
  • multipart/alternative holds the same content in several forms, usually plain text and HTML. The email client shows the best form it can.
  • multipart/mixed holds a body plus attachments.
  • multipart/related holds an HTML body together with the resources it uses, such as inline images.
  • application/pdf, image/png, image/jpeg and similar types label attached files by what they are.
  • application/octet-stream is a generic label for "binary data of unknown type".

What a MIME email looks like

This simplified example shows an email with a plain-text part, an HTML part and a PDF attachment. The boundary strings separate the parts, and the encoded file content is shortened.

From: Billing <[email protected]>
To: [email protected]
Subject: Your invoice
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="mixed-1"

--mixed-1
Content-Type: multipart/alternative; boundary="alt-1"

--alt-1
Content-Type: text/plain; charset=UTF-8

Your invoice is attached.
--alt-1
Content-Type: text/html; charset=UTF-8

<p>Your invoice is attached.</p>
--alt-1--

--mixed-1
Content-Type: application/pdf; name="invoice.pdf"
Content-Disposition: attachment; filename="invoice.pdf"
Content-Transfer-Encoding: base64

JVBERi0xLjQK...
--mixed-1--

The structure is nested. The outer multipart/mixed part contains the body and the attachment, and the body is itself a multipart/alternative part with a plain-text and an HTML version. You rarely write this by hand. Libraries and sending services build it for you, but understanding the shape helps when something goes wrong. To see the real structure of a message you received, view its source, as described in how to read email headers.

Encoding: why attachments grow

Mail systems were built for text, so binary content such as a PDF or an image must be converted to text characters. The most common method, base64, represents every three bytes of data with four characters, which makes the encoded data about a third larger. A 10 MB file therefore becomes roughly 13 to 14 MB in the message, and the limit that matters is the size of the whole encoded message. For limits and practical advice, see email size limits and attachments. For text with accents and other non-ASCII characters, quoted-printable is often used for the body, and header values use a special encoding format defined in RFC 2047.

Inline images and attachments

An attachment is a file that the recipient downloads or opens. An inline image appears inside the HTML body. To embed an image, the message includes it as a part with a Content-ID, and the HTML refers to it with src="cid:logo123". Many email clients block remote images by default, so embedded images may appear without a click, though some clients treat them differently. Many senders prefer to link to hosted images instead, because it keeps the message small and lets them update the image. Whichever you choose, write helpful alt text and make sure the message makes sense without images. See accessible HTML email and dark mode.

Why you should send both text and HTML

A multipart/alternative message with plain-text and HTML parts works for every client, including those that block HTML, screen readers and some corporate gateways. A message with only an HTML part, or an HTML part with an unrelated plain-text part, looks careless, and filters may treat it with suspicion. Generate the text part from the same content as the HTML part. See email content and spam filters for more.

Common MIME problems and fixes

ProblemLikely causeFix
Garbled characters such as "é"The charset is missing or does not match the real encodingDeclare UTF-8 in Content-Type and encode the body as UTF-8
Attachment appears as a strange file or "winmail.dat"The sending client used a proprietary format, or the wrong content typeSend in standard MIME, and set the correct content type
Attachment missingThe message was not multipart/mixed, or a gateway stripped the fileCheck the structure in the source, and the recipient's security policy
Inline image shows as a broken box or a paperclipThe Content-ID does not match the cid reference, or the part is not inside multipart/relatedMatch the identifiers and nest the parts correctly
Subject shows odd symbolsNon-ASCII characters in a header that were not encodedEncode header values as RFC 2047 requires, or use a library that does
Message rejected as too largeThe encoded size is above a limitSend a link, or compress the file

Building MIME messages with code

Do not assemble MIME messages by concatenating strings. Use a library, such as Python's email package, or the message-building features of Nodemailer, which take care of boundaries, encoding and headers. See our Nodemailer guide for attachments in Node.js. If you send through an API, you give the service the fields and files, and it builds the MIME message for you; see SMTP versus API to decide which fits.

# Python: a message with text, HTML and an attachment
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
msg["Subject"] = "Your invoice"
msg.set_content("Your invoice is attached.")
msg.add_alternative("<p>Your invoice is attached.</p>", subtype="html")
with open("invoice.pdf", "rb") as f:
    msg.add_attachment(f.read(), maintype="application", subtype="pdf", filename="invoice.pdf")

Be careful with attachments you did not create. Attachments are a common route for malware, and many mail systems scan or block risky file types. Do not allow users to attach arbitrary files to messages that your system sends, and never trust a file name or content type supplied by someone else.

Checking your own messages

The quickest way to learn MIME is to look at real messages. Send a test email from your application to a mailbox you control, open the option that shows the original message or its source, and find the Content-Type lines. Count the boundaries, check that the plain-text and HTML parts are both present, and that attachments have the file name and type you expect. Do this once for each kind of message your system sends, such as receipts, notifications and campaigns, since each is often built by different code. A few minutes of reading raw source will explain most formatting and attachment problems that otherwise take hours to guess at.

Send rich email without hand-building MIME Send HTML and plain text, attachments and templates through our SMTP relay or email API, and we handle the message structure.

See the email API

References and further reading

Frequently asked questions

What is MIME in email?

MIME, or Multipurpose Internet Mail Extensions, is the standard that lets email carry attachments, HTML, inline images and text in any language by describing the content type and encoding of each part.

What is multipart/alternative?

It holds the same content in several forms, usually plain text and HTML, so the email client can show the best form it supports. Sending both is good practice.

Why are email attachments larger than the original file?

Binary files are encoded as text, usually base64, which makes the data about a third larger. The limit that matters is the size of the whole encoded message.

How do inline images work in email?

The image is included as a part with a Content-ID and the HTML refers to it with a cid reference. Many senders instead link to hosted images to keep messages small.

Why do I see garbled characters in an email?

Usually the charset is missing or does not match the real encoding. Declare UTF-8 in the Content-Type header and encode the body as UTF-8.

Topics#mime#attachments#multipart#content type#base64#inline images#email headers
Was this guide helpful?Your answer helps us improve our documentation.

Start sending in minutes.

Create an account, add your domain and send your first email.

Get started Talk to sales