The Setup
If you’re running WordPress on Azure App Service with WooCommerce and the Microsoft App Service Email plugin (v1.2.1) connected to Azure Communication Services (ACS), you may have noticed something maddening: basic emails work perfectly — contact forms, password resets, freight quote requests — but WooCommerce order notification emails fail silently with this error in your Azure Email Logs:
Request body validation error. ContentBytes invalid. Should be base64You check the plugin settings. Everything looks right. ACS is connected. The sender address is valid. Other emails go through without a hitch. But the moment WooCommerce tries to send an order confirmation, it dies.
Why It Happens
WooCommerce order emails include an attached invoice PDF generated at runtime and stored in a WordPress temp directory. The App Service Email plugin handles attachments in generate_request_body() inside:
/admin/mailer/class-azure_app_service_email-controller.phpThe relevant code block looks like this:
$filePaths = is_array($attachments) ? $attachments : explode("\n", str_replace("\r\n", "\n", $attachments));
foreach ($filePaths as $path) {
if ($path[0] !== '/') {
$path = ABSPATH . trim($path); // ← Wrong root on Azure containers
}
if (file_exists($path)) {
$attachmentContent = base64_encode(file_get_contents(trim($path)));
...
}
}The logic looks reasonable — if the path doesn’t start with /, prepend ABSPATH to make it absolute. The problem is ABSPATH on Azure App Service points to the wrong place.
On a standard WordPress installation, ABSPATH and the actual WordPress root are the same. On Azure App Service’s containerized WordPress environment, they’re not. The container exposes multiple paths:
/var/www/html ← ABSPATH (what PHP thinks)
/var/www/wordpress ← actual running WordPress root
/home/site/wwwroot ← persistent storage mountWhen WooCommerce passes an attachment path that doesn’t begin with / — which temp file paths sometimes don’t — the plugin prepends the wrong ABSPATH, file_exists() returns false, the attachment is silently dropped, and ACS receives a malformed request body that fails validation.
The base64 error is a red herring. The real issue is a path mismatch causing an empty or malformed attachment payload
The Diagnosis
The fastest way to confirm this is the culprit: check whether emails without attachments work. If your contact forms, password reset emails, and other non-attachment emails go through fine but WooCommerce order emails fail — this is your bug.
You can also SSH into your App Service container and verify the path mismatch yourself:
# Azure Portal → App Service → SSH → Go
php -r "echo ABSPATH . PHP_EOL;"
php -r "echo WP_CONTENT_DIR . PHP_EOL;"On a healthy standard install these resolve to the same parent. On Azure App Service containers they often don’t.
The Fix
SSH into your App Service container and back up the controller file first:
cp /var/www/wordpress/wp-content/plugins/app_service_email/admin/mailer/class-azure_app_service_email-controller.php \
/var/www/wordpress/wp-content/plugins/app_service_email/admin/mailer/class-azure_app_service_email-controller.php.bakThen apply the patch using Python (cleaner than sed for multi-line PHP edits):
python3 -c "
path = '/var/www/wordpress/wp-content/plugins/app_service_email/admin/mailer/class-azure_app_service_email-controller.php'
with open(path, 'r') as f:
content = f.read()
old = ''' foreach (\$filePaths as \$path) {
if (\$path[0] !== '/') {
\$path = ABSPATH . trim(\$path);
}'''
new = ''' foreach (\$filePaths as \$path) {
\$path = trim(\$path);
if (empty(\$path)) { continue; }
if (\$path[0] !== '/') {
\$wp_root = rtrim(str_replace('wp-content', '', WP_CONTENT_DIR), '/');
\$path = \$wp_root . '/' . \$path;
}'''
if old in content:
content = content.replace(old, new)
with open(path, 'w') as f:
f.write(content)
print('PATCHED OK')
else:
print('PATTERN NOT FOUND - no changes made')
"Verify the patch landed correctly:
grep -A 10 'foreach (\$filePaths as \$path)' \
/var/www/wordpress/wp-content/plugins/app_service_email/admin/mailer/class-azure_app_service_email-controller.phpYou should see:
foreach ($filePaths as $path) {
$path = trim($path);
if (empty($path)) { continue; }
if ($path[0] !== '/') {
$wp_root = rtrim(str_replace('wp-content', '', WP_CONTENT_DIR), '/');
$path = $wp_root . '/' . $path;
}
if (file_exists($path)) {
$attachmentContent = base64_encode(file_get_contents(trim($path)));
What the Fix Does
The patch makes three improvements over the original code:
- Trims all paths immediately — whitespace in attachment paths is a common source of silent
file_exists()failures. - Skips empty paths gracefully — instead of crashing on an empty string with
$path[0], it continues to the next attachment cleanly. - Uses
WP_CONTENT_DIRinstead ofABSPATH—WP_CONTENT_DIRreliably resolves to the active WordPress content directory on Azure App Service containers. Working backwards from it usingstr_replace('wp-content', '', WP_CONTENT_DIR)gives you the true WordPress root regardless of which container path the runtime is using.
Testing
After applying the patch, trigger a WooCommerce order notification:
- Go to WooCommerce → Orders → [any order]
- Change the status to Processing and save
- Check your admin email — the order notification with attachment should arrive within seconds
- Confirm in WordPress Admin → Azure Email Logs that the send shows Success
The Easy Route — PowerShell Automation
We’ve also created a PowerShell automation script that connects to your App Service via the Kudu REST API — no SSH session required — and handles detection, backup, patching, and verification in a single run.
github.com/JONeillSr/Repair-AppServiceEmailAttachmentPatch
Important Caveat — Plugin Updates
This patch modifies a Microsoft-maintained plugin file directly. It will be overwritten if the plugin is updated through WordPress. After any plugin update, re-apply the patch or check whether Microsoft has addressed the path resolution in a newer version.
We’ve submitted this fix upstream to the Azure WordPress App Service plugins repository. The change is small, safe, and benefits every WooCommerce store running on Azure App Service.
Environment
Confirmed working on:
- Azure App Service — Linux, containerized WordPress
- App Service Email Plugin — v1.2.1 by Microsoft
- WooCommerce — 8.x+
- PHP — 8.x
About Azure Innovators
At Azure Innovators, we turn technological challenges into opportunities for growth. Our expert consultants bring decades of combined experience to deliver innovative solutions that drive our clients’ businesses forward. Whether you need help implementing modern authentication, securing your Microsoft 365 environment, or designing a comprehensive cloud security strategy, we’re here to help.
Want to learn more about passwordless authentication or need help implementing TAP in your organization? Get in touch with our team today.