Azure Innovators

Isometric illustration of two Azure server towers showing a broken ABSPATH path on the left and a correct WP_CONTENT_DIR path delivering a WooCommerce email attachment with checkmark on the right
The ABSPATH bug sends WooCommerce email attachments down the wrong path inside the Azure App Service container — this fix routes them correctly using WP_CONTENT_DIR.

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 base64

You 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.


 

Isometric illustration of a magnifying glass over an error log screen with a red herring fish floating above a broken file path chain showing the misleading ContentBytes base64 error in Azure Communication Services
The "ContentBytes invalid. Should be base64" error is a red herring — the attachment was never encoded because it was never found. The real culprit is a broken file path.

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.php

The 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 mount

When WooCommerce passes an attachment path that doesn’t begin with / — which temp file paths sometimes don’t — the plugin prepends the wrong ABSPATHfile_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

Isometric illustration of a glowing terminal window inside an Azure cloud with a stethoscope and two PHP command outputs — one in red showing the wrong ABSPATH path and one in green showing the correct WP_CONTENT_DIR path for WordPress diagnosis
A quick SSH session into your App Service container and two PHP one-liners reveal the path mismatch instantly — ABSPATH and WP_CONTENT_DIR resolve to different roots.

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.

Isometric illustration of a robotic Python snake surgeon operating on a PHP plugin file document on a surgical table, using a laser scalpel to replace a red incorrect code line with a green corrected line, with a backup file and verification screen nearby
A targeted Python one-liner performs surgical precision on the plugin file — replacing the broken ABSPATH line with the correct WP_CONTENT_DIR path, backing up the original, and verifying the result.

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.bak

Then 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.php

You 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)));
Isometric illustration of a WooCommerce cart with a PDF invoice attachment sending an email through an Azure Communication Services cloud to an open inbox with a green checkmark and paperclip icon, surrounded by celebration confetti

What the Fix Does

The patch makes three improvements over the original code:

  1. Trims all paths immediately — whitespace in attachment paths is a common source of silent file_exists() failures.
  2. Skips empty paths gracefully — instead of crashing on an empty string with $path[0], it continues to the next attachment cleanly.
  3. Uses WP_CONTENT_DIR instead of ABSPATH — WP_CONTENT_DIR reliably resolves to the active WordPress content directory on Azure App Service containers. Working backwards from it using str_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:

  1. Go to WooCommerce → Orders → [any order]
  2. Change the status to Processing and save
  3. Check your admin email — the order notification with attachment should arrive within seconds
  4. Confirm in WordPress Admin → Azure Email Logs that the send shows Success
Isometric illustration of a PowerShell terminal with three robotic arms representing az CLI authentication, PHP file patch detection, and automated repair, connected to an Azure cloud via Kudu REST API with a green checkmark result
The PowerShell automation script 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.

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.

Leave a Reply