Power Automate: Embed a Base64 Image in an Email (and Why It May Not Show)

Your flow has an image — a SharePoint or OneDrive file, an HTTP response payload — and you want it inside the email body, not dangling off the message as an attachment. Power Automate has no built-in "insert picture" button, so the reliable route is a Base64 data URI in the HTML body. Below is the exact working pattern, a lighter variant when your data is already Base64, and the four reasons the image still shows up blank — with fixes for each.

The working pattern

Three actions in sequence:

  1. Get file content — point it at your SharePoint or OneDrive file. This action returns the raw binary of the image.
  2. Compose — with the expression:
base64(body('Get_file_content'))
  1. Send an email (V2) — with the image referenced in the HTML body:
<img src="data:image/png;base64,@{outputs('Compose')}" width="200" alt="Logo">

Two details make or break this:

You can skip the Compose action and inline the expression directly, which is handy for one-off flows:

<img src="data:image/png;base64,@{base64(body('Get_file_content'))}" width="200">

Power Automate also offers a dataUri() expression, but it is designed for text values — for binary file content, stick with base64(body(...)) and add the prefix yourself.

Embedding as a data URI has one cosmetic advantage over attachments: the image travels inside the HTML body, so received mail shows no attachment icon. This is the cleanest of the approaches for logos and small inline graphics.

If your data is already Base64

When the Base64 comes from your own data — an API response, a webhook payload, a database column — you do not need base64() at all. You need the right wrapper:

Three ways to get an image into the email

Inline data URI vs. hosted URL vs. attachment in Power Automate
MethodNo attachment iconRenders in Outlook desktop?Best for
Base64 data URI in bodyYesNoSmall logos/icons in mail read in Gmail, Apple Mail, Thunderbird, Outlook web*
Hosted HTTPS URLYesYesNewsletters, templates, anything recipient-agnostic
Email attachmentNoYesFiles the recipient should keep (invoices, reports)

*Outlook on the web is inconsistent with data URIs; Outlook desktop never renders them. Treat hosted URLs as the only universal option.

The trade-off is not specific to Power Automate — it is how email clients treat data URIs. The client-by-client breakdown is in the Base64 image not showing in Outlook guide.

Image not showing? The 4 causes

  1. Wrong or missing MIME prefix. data:image/png on a JPEG payload (or a forgotten prefix entirely) breaks rendering everywhere. Check what the source file actually is before wiring the prefix.
  2. The image is too large. Inline Base64 images of roughly 1 MB or more are repeatedly reported to fail to render in Power Automate emails, even where data URIs are otherwise supported. Compress before encoding (next section).
  3. The expression never evaluated. Open the received email's raw HTML (or the flow run history, Compose output) and look for literal @{...} braces or an empty src. If the Compose output is empty, the Get file content step returned nothing — check the file path and permissions.
  4. The recipient is on Outlook desktop. The Word rendering engine has no data URI support — the image was embedded correctly and the client still refuses it. The fix is a hosted HTTPS URL or a CID inline attachment; both are covered in the Outlook guide. The same class of restriction explains Gmail's handling of inline Base64.

A fifth pitfall sits one field over: the Attachments Content field expects binary content, not Base64 text. If you paste a Base64 string there, it can be converted to binary a second time and arrive corrupted. Use the body-embed pattern above for inline images; for true attachments, feed the field the raw file content directly.

Keep the payload small

Base64 encoding adds about 33% overhead on top of the file size, and the result lives inside the email HTML — a 300 KB logo becomes a 400 KB email before any text is added. Before encoding:

If the image is destined for a signature rather than a flow-generated email, the mechanics differ per client — start from the Base64 image in email signature guide.

Frequently asked questions

How do I embed an image in a Power Automate email without showing it as an attachment?

Get file content → Compose with base64(body('Get_file_content')) → reference it in the Send an email (V2) body as <img src="data:image/png;base64,@{outputs('Compose')}">. The image rides inside the HTML, so no attachment icon appears.

Why is my Power Automate Base64 image not showing?

In order of likelihood: wrong MIME prefix, image too large (~1 MB and up fails), the expression pasted as literal text instead of evaluated, or the recipient is on Outlook desktop which never renders data URIs.

Can I use base64() directly in the img src?

Yes — @{base64(body('Get_file_content'))} inline works. The Compose step is nicer for reuse and debugging.

Why does the image fail when the file is large?

Inline images live inside the email HTML; around 1 MB of Base64 the mail pipeline may stop rendering them. Compress or resize first — Base64 adds ~33% on top.

Why does the Attachments Content field break my Base64 string?

That field expects binary content; a Base64 string passed there can get converted to binary again and arrive corrupted. For attachments, pass raw file content; the data URI pattern is for the HTML body.

Will it show for Outlook desktop recipients?

No. Outlook desktop has no data URI support regardless of how the flow built the image. Use a hosted HTTPS URL or a CID attachment for Outlook audiences.

Building the Base64 string by hand? Encode it in the browser with the Image to Base64 converter, check the final weight with the size calculator, and paste the HTML output straight into your flow's email body.