How to Send Emails with Attachments in Power Automate (Without 0KB Files)
Getting email attachments right in Power Automate is trickier than it looks. Here's how to attach files from SharePoint, Dataverse, and other sources without ending up with empty 0KB files.
Sending an email from Power Automate is simple. Sending an email with an attachment that actually contains data? That’s where people run into problems. The most common complaint: “My flow sends the email fine, but the attachment is 0KB.”
Here’s how to get attachments right with every common source.
Which Email Connector to Use
Power Automate has multiple email connectors. The ones you’ll see most:
- Office 365 Outlook — The standard choice if your organization uses Microsoft 365. Sends from the connected user’s mailbox.
- Send an email notification (Mail) — Sends from a generic Microsoft address. No attachments support, limited formatting. Avoid it for anything beyond simple notifications.
- Outlook.com — For personal accounts. Not what you want in a business flow.
For attachments, use Office 365 Outlook and the Send an email (V2) action.
Attaching a File from SharePoint
This is the most common scenario. The key: you need the file content, not the file metadata.
Step 1: Use Get file content (not “Get file properties”) from the SharePoint connector.
Step 2: In the Send an email action, switch to the advanced Attachments input. Click “Switch to input entire array” or add an attachment item with:
- Name: The file name including extension, e.g.,
Report.pdf - Content: The output from the Get file content action
[
{
"Name": "Report.pdf",
"ContentBytes": @{body('Get_file_content').$content}
}
]
If you’re using the visual designer, just map the outputs:
- Attachments Name: Use the
File name with extensionfrom a “Get file properties” action, or type the name manually. - Attachments Content: Use the
File Contentoutput from “Get file content.”
Why the File Arrives at 0KB
The number one cause: you used Get file properties instead of Get file content. File properties gives you metadata (name, size, URL). File content gives you the actual bytes. You need both actions — properties for the name, content for the data.
Attaching a File from Dataverse
Dataverse stores files in two ways: the legacy Notes/Annotations table and the newer File/Image columns.
From Notes (Annotations)
Notes store attachments as Base64 in the documentbody field.
Step 1: List rows from the Notes table, filtering by the parent record:
_objectid_value eq '{recordGUID}'
Step 2: For each note with an attachment:
- Name:
filenamefield from the note - Content: Use an expression to decode:
base64ToBinary(items('Apply_to_each')?['documentbody'])
From File Columns
If the table has a File-type column, use the Download a file or an image action from the Dataverse connector. The output is already binary content — pass it directly to the attachment Content field.
Attaching Files from an HTTP Request
If you’re getting a file from an external API:
[
{
"Name": "data-export.csv",
"ContentBytes": @{body('HTTP')}
}
]
If the API returns Base64-encoded content instead of raw bytes:
[
{
"Name": "data-export.csv",
"ContentBytes": @{base64ToBinary(body('HTTP'))}
}
]
Multiple Attachments
To send multiple attachments, build an array. Initialize an Array variable before your loop, then append to it:
Step 1: Initialize variable varAttachments as Array, value []
Step 2: Inside your loop (ForEach over files):
Append to array:
{
"Name": "@{items('Apply_to_each')?['fileName']}",
"ContentBytes": "@{body('Get_file_content').$content}"
}
Step 3: In Send an email, switch Attachments to “input entire array” and pass @{variables('varAttachments')}.
Dynamic File Names
Don’t hardcode file names. Build them from your flow data:
@{formatDateTime(utcNow(), 'yyyy-MM-dd')}_Invoice_@{triggerOutputs()?['body/invoicenumber']}.pdf
This gives you something like 2026-03-22_Invoice_INV-1042.pdf.
Size Limits
The Office 365 Outlook connector has a 150 MB total message size limit (including body and all attachments). For most practical purposes, keep total attachment size under 25 MB to avoid issues with recipient mailboxes.
If you’re attaching large files, consider sending a sharing link instead:
"Please find the file here: @{outputs('Create_sharing_link')?['body/link/webUrl']}"
Common Mistakes and How to Fix Them
Attachment Is 0KB
As mentioned above: you used the wrong SharePoint action. Use Get file content for the bytes, not Get file properties.
Attachment Has the Wrong Name or No Extension
The Name field needs the full filename including extension. If you pass "Report" instead of "Report.pdf", the recipient gets a file with no extension that their computer won’t know how to open.
”InvalidTemplate” Error on the Attachment Expression
This usually means your expression syntax is wrong. The most common issue: mixing up $content and body(). For SharePoint file content, use body('Get_file_content').$content. For Dataverse notes, use base64ToBinary() on the documentbody field.
The Email Sends But No Attachment Appears
Check that the Attachments section is configured in array mode. If you’re passing a single attachment object without the array brackets [], the connector silently ignores it in some configurations. Always wrap in an array.
Base64 Content Appears as Text in the Email Body
You accidentally put the file content in the body instead of the attachment. Double-check that your dynamic content is mapped to the Attachments Content field, not the Body field.
Related articles
Your First Approval Flow
A step-by-step guide to building approval flows in Power Automate, including connector provisioning, approval types, custom email content, and handling the response — plus the errors that block most first-time setups.
Calling Power Automate from a Canvas App (And Getting Data Back)
Calling a flow from a canvas app is straightforward once you get the trigger right. Here's how to set up inputs, return data to the app, and fix the issues that come up when the two don't talk to each other.
Power Automate Formatting Cheat Sheet
formatDateTime, convertTimeZone, formatNumber — these expressions handle 90% of formatting needs in Power Automate. Here's the syntax, common format strings, and fixes for the errors that come up.