DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk17 min

Phpmailer Could not access file – PHP

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PHPMailer throws the “Could not access file” error when it cannot read the file you pass to methods such as addAttachment() or addEmbeddedImage(). The file may be missing, the path may resolve differently than expected, or the web server user may not have permission to access it.

This problem is especially common when using relative paths, upload directories, shared hosting, temporary files, or scripts executed from different working directories. A path that looks correct in your project may not be the same path PHP sees at runtime.

As an Amazon Associate I earn from qualifying purchases.

To fix it, you need to confirm the real file location, check that PHP can read it, and account for server restrictions such as ownership, permissions, open_basedir, or disabled access to certain directories. Practical checks before calling addAttachment() can quickly reveal whether the issue is the path, the file itself, or the hosting environment.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What the “Could Not Access File” Error Means in PHPMailer

In PHPMailer, the message “Could not access file” usually appears when you call methods such as addAttachment() or addEmbeddedImage() and PHPMailer cannot read the file you asked it to include. The file path may look correct in your PHP code, but PHPMailer still has to resolve that path from the running script’s environment, confirm that the file exists, and open it with the permissions available to the web server or PHP process.

A typical failing example looks like this:

$mail->addAttachment('uploads/invoice.pdf');

If uploads/invoice.pdf is not located relative to the script’s current working directory, or if the file exists but cannot be read by PHP, PHPMailer throws the error before sending the email. The same can happen with embedded images:

$mail->addEmbeddedImage('images/logo.png', 'logo_cid');

This error is not usually an SMTP problem. It does not mean your mail server rejected the message, your credentials are wrong, or the recipient address is invalid. The failure happens earlier, while PHPMailer is building the MIME message and trying to attach local file content. If PHPMailer cannot open the file, it cannot encode it into the email, so the send process is stopped.

What PHPMailer is checking

When you add a file, PHPMailer needs the path to point to a real, readable file on the server. In practical terms, all of the following must be true:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • The path passed to addAttachment() or addEmbeddedImage() must be correct.
  • The file must exist at that exact location on the server, not just on your local computer.
  • The file must not be a directory.
  • The PHP process must have permission to read the file.
  • Server restrictions such as open_basedir must allow PHP to access that location.

For example, this call may work on a development machine but fail after deployment:

$mail->addAttachment('C:\Users\me\Desktop\report.pdf');

On a Linux hosting server, that Windows path has no meaning. Similarly, this may fail if the script is executed from a different directory than expected:

$mail->addAttachment('../files/report.pdf');

Relative paths depend on the current working directory, which is not always the same as the directory containing the PHP file. This is especially common in frameworks, cron jobs, CMS plugins, and routed applications where the entry point may be public/index.php rather than the file where the mail code is written.

How the error commonly appears

Depending on how your code handles PHPMailer exceptions, you may see the error as an exception, a returned error message, or part of $mail->ErrorInfo. For example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Could not access file: uploads/invoice.pdf

That filename in the message is the path PHPMailer attempted to use. It is the first value to inspect when diagnosing the problem. If the path is relative, convert it mentally or programmatically into the full server path and check whether the file is really there.

The most reliable way to think about this error is: PHPMailer was asked to attach or embed a file, but PHP could not read that file from the server filesystem. The fix is therefore usually found in path construction, upload handling, filesystem permissions, or hosting restrictions rather than in mail transport settings.

Common Causes: Wrong Paths, Missing Files, and Permissions

PHPMailer raises “Could not access file” when the path passed to addAttachment(), addEmbeddedImage(), or a related method cannot be opened by the PHP process. In most cases, the file is not where the script thinks it is, the path is being resolved from a different working directory, or the web server user does not have permission to read it. The error is usually not caused by SMTP settings; it happens before the message is sent, while PHPMailer is preparing the MIME body.

Wrong or misleading file paths

A common mistake is passing a browser URL or a relative path that does not match PHP’s current execution context. PHPMailer expects a server-side filesystem path, not a public web address. For example, this is usually wrong:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

$mail->addAttachment('https://example.com/uploads/invoice.pdf');

Instead, pass the local path to the file on disk, such as:

$mail->addAttachment('/var/www/example.com/public/uploads/invoice.pdf');

Relative paths can also fail when the script is executed from a different directory than expected. A file path like uploads/invoice.pdf may work from one controller or test script but fail from a cron job, queue worker, included PHP file, or framework entry point. PHP resolves relative paths based on the current working directory, not necessarily the directory containing the file where addAttachment() is written.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Missing files or files created too late

The file may simply not exist at the moment PHPMailer tries to attach it. This often happens with generated PDFs, exported CSV files, image uploads, or temporary files. For instance, a script may create invoice.pdf, then store the wrong filename in the database, or delete the temporary file before calling addAttachment(). Upload handling can also be involved: if a file was uploaded through a form but not moved from PHP’s temporary upload directory using move_uploaded_file(), the path saved for later use may no longer be valid.

  • Wrong filename: the database stores invoice-123.pdf, but the actual file is invoice_123.pdf.
  • Wrong directory: the file is saved in /storage/app/uploads, but PHPMailer is given /public/uploads.
  • Temporary file removed: a generated report is deleted before the email is built.
  • Case mismatch: Report.pdf and report.pdf are different files on Linux servers.

Permission and ownership problems

Even when the path is correct and the file exists, PHP still needs read access. On many Linux servers, PHP runs as a user such as www-data, apache, nginx, or a hosting-account user. If the attachment is owned by another user and has restrictive permissions, PHPMailer cannot open it. A file with permissions like 600 may be readable only by its owner, while a directory without execute permission cannot be traversed even if the file itself is readable.

Problem Example Practical fix
File not readable -rw------- invoice.pdf Allow the PHP user to read it, commonly with suitable group ownership and 640 or 644.
Directory not accessible drwx------ uploads/ Ensure the PHP user can traverse the directory, commonly using 750 or 755 as appropriate.
Wrong owner Files created by a deploy user, read by www-data Set ownership or group membership so PHP can read uploaded and generated files.

Shared hosting adds a few extra pitfalls. Some providers restrict access outside the account’s home directory with open_basedir, disable access to certain temporary directories, or run cron jobs under a different user than web requests. A path that works in the browser may fail in a scheduled script, and a file created by a command-line process may not be readable by the PHP-FPM pool serving the site. When diagnosing this error, check the exact path, confirm the file exists at send time, and verify that the same PHP user running the mail script can read both the file and every directory above it.

How to Verify File Paths Before Calling addAttachment()

Before passing a file to addAttachment(), verify that PHP can see and read the exact path you are about to use. PHPMailer does not search for files automatically; it receives a string path and asks PHP to open that file. If the path is wrong, points to a directory, references a file outside the allowed filesystem area, or cannot be read by the web server user, PHPMailer will throw the “Could not access file” error.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A practical approach is to check the file with PHP first, then call addAttachment() only after the checks pass. Use file_exists() to confirm the path exists, is_file() to make sure it is a regular file, and is_readable() to confirm PHP has permission to read it. This is especially useful when the filename comes from a database, an upload form, or dynamically generated invoice/report .

$filePath = __DIR__ . '/uploads/invoice-123.pdf';

if (!file_exists($filePath)) {
die('Attachment not found: ' . $filePath);
}

if (!is_file($filePath)) {
die('Attachment path is not a file: ' . $filePath);
}

if (!is_readable($filePath)) {
die('Attachment is not readable: ' . $filePath);
}

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

$mail->addAttachment($filePath, 'invoice-123.pdf');

When diagnosing the problem, print or log the resolved path rather than guessing. A common mistake is assuming the script runs from the same directory as the PHP file being edited. Relative paths can resolve differently depending on the entry point, framework router, cron job, or include structure. Using __DIR__ helps anchor the path to the current PHP file’s directory.

error_log('Attachment path: ' . $filePath);
error_log('Real path: ' . realpath($filePath));
error_log('Current working directory: ' . getcwd());

realpath() can help reveal the actual filesystem location, but it returns false if the file does not exist. That makes it useful for diagnostics, not as the only way to build paths. If realpath($filePath) is empty or false, the file path is probably wrong, the file has not been created yet, or part of the directory chain is inaccessible.

Checklist before adding the attachment

  • Confirm the final string path: log the value passed to addAttachment().
  • Check existence: use file_exists($filePath).
  • Check file type: use is_file($filePath), not just file_exists().
  • Check readability: use is_readable($filePath).
  • Check the working directory: compare getcwd() with where you think the script is running.
  • Check generated files: make sure PDFs, CSVs, or images are fully written before attaching them.

If you are attaching an uploaded file, verify the temporary upload path before using it. For example, $_FILES['document']['tmp_name'] should exist and be readable during the same request. If you move the upload first with move_uploaded_file(), attach the new destination path, not the old temporary path.

$uploadPath = __DIR__ . '/uploads/' . basename($_FILES['document']['name']);

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

if (move_uploaded_file($_FILES['document']['tmp_name'], $uploadPath)) {
if (is_readable($uploadPath)) {
$mail->addAttachment($uploadPath);
}
}

For files created by another process, such as a PDF generator or scheduled export, add a verification step after generation. Confirm that the file size is greater than zero with filesize() and that PHP can read it from the same process that sends the email. This avoids trying to attach a file that exists in name only, is still being written, or was created in a different directory than expected.

Using Absolute Paths Instead of Relative Paths

When PHPMailer reports “Could not access file” during addAttachment() or addEmbeddedImage(), relative paths are often the source of the problem. A path like uploads/invoice.pdf is not resolved relative to the file where you wrote the code in every situation. It is resolved relative to PHP’s current working directory, which can change depending on how the script is executed, included, routed through a framework, or triggered by a cron job.

For example, this may work when you open one PHP file directly, but fail when the same mail-sending code is called from another script:

$mail->addAttachment('uploads/invoice.pdf');

A safer approach is to build an absolute filesystem path before passing it to PHPMailer. An absolute path points to the file from the server’s root directory, not from the URL and not from the current PHP script location. On Linux hosting it may look like /home/account/public_html/uploads/invoice.pdf. On Windows it may look like C:\inetpub\wwwroot\site\uploads\invoice.pdf.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Build paths from a known directory

Use constants such as __DIR__ to anchor the path to the directory of the current PHP file. This avoids surprises caused by includes, front controllers, or command-line execution:

$filePath = __DIR__ . '/uploads/invoice.pdf';
$mail->addAttachment($filePath);

If your mail script is inside a subdirectory, adjust the path accordingly:

$filePath = __DIR__ . '/../uploads/invoice.pdf';
$mail->addAttachment($filePath, 'invoice.pdf');

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The second argument to addAttachment() is optional, but useful. It lets you control the filename shown to the recipient while keeping the real server path private and stable.

Do not use URLs for attachments

PHPMailer expects a local filesystem path for addAttachment(), not a public web URL. This is a common mistake:

$mail->addAttachment('https://example.com/uploads/invoice.pdf');

Instead, use the server path to the same file:

$mail->addAttachment('/home/account/public_html/uploads/invoice.pdf');

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If the file exists only on a remote server, download it first to a temporary local file, verify it was saved correctly, and then attach that local file. For generated PDFs or reports, save the output to a known directory before calling addAttachment().

Check the resolved path before sending

Before passing the file to PHPMailer, print or log the final path during testing. This quickly reveals whether PHP is looking in the expected location:

$filePath = __DIR__ . '/uploads/invoice.pdf';
error_log('Attachment path: ' . $filePath);

if (!file_exists($filePath)) {
    throw new Exception('Attachment file not found: ' . $filePath);
}

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

if (!is_readable($filePath)) {
    throw new Exception('Attachment file is not readable: ' . $filePath);
}

$mail->addAttachment($filePath);

  • __DIR__ gives the directory of the current PHP file.
  • getcwd() shows PHP’s current working directory, which may be different.
  • realpath() can confirm the canonical absolute path, but returns false if the file does not exist.

On shared hosting, the absolute path is usually not the same as the domain name. A browser URL such as https://example.com/uploads/file.pdf may map internally to /home/username/public_html/uploads/file.pdf. Hosting control panels often show this path in file manager details, PHP info pages, or application settings. Once you use the real filesystem path and confirm the file exists and is readable, PHPMailer can access the attachment consistently across direct requests, includes, framework routes, and scheduled tasks.

Fixing File Permission and Ownership Problems

Even when the attachment path is correct, PHPMailer can still throw “Could not access file” if the PHP process is not allowed to read the file. This commonly happens after files are uploaded by FTP, generated by a cron job, created by another system user, or stored outside the public web directory. PHPMailer does not bypass the operating system’s file access rules; when you call addAttachment() or addEmbeddedImage(), PHP must be able to open that file for reading.

Start by checking the file’s permissions and owner on the server. On Linux hosting, a file such as /home/example/app/storage/invoices/invoice-1024.pdf may exist, but it may be owned by a different user than the one running PHP, such as root, deploy, or another cPanel account. Directories in the path also need execute permission so PHP can traverse them. A readable file inside an unreadable directory will still fail.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended permission checks

  • Files: commonly 0644, allowing the owner to write and others in the allowed context to read.
  • Directories: commonly 0755, allowing traversal into the directory.
  • Private storage: use tighter permissions if PHP runs as the same user that owns the files.
  • Uploads: confirm the final moved file is readable after move_uploaded_file().

On a VPS or dedicated server, you can inspect the path with commands such as ls -l and namei -l. The second command is especially useful because it shows permissions for every directory in the path. If your file is owned by the wrong user, adjust ownership to match the PHP/web user used by your stack. Depending on the server, this may be www-data, apache, nginx, or the hosting account user.

Problem Example fix
File is not readable by PHP chmod 644 invoice.pdf
Directory cannot be traversed chmod 755 storage storage/invoices
File owned by the wrong user chown www-data:www-data invoice.pdf
Generated file created with restrictive permissions Set permissions after creation with chmod($file, 0644)

In PHP, add a small access check before handing the file to PHPMailer. This makes the failure clearer and separates a PHPMailer issue from a filesystem issue. For example, verify the file exists and is readable before calling addAttachment():

$file = '/home/example/app/storage/invoices/invoice-1024.pdf'; if (!is_file($file) || !is_readable($file)) { throw new RuntimeException('Attachment is missing or not readable: ' . $file); } $mail->addAttachment($file, 'invoice-1024.pdf');

Shared hosting can add extra restrictions. Some providers use open_basedir, CageFS, jailed shells, or account isolation, which prevents PHP from reading files outside approved directories even if Unix permissions look correct. In that case, move attachments into an allowed application storage directory, update the configured base directory, or ask the host to confirm which paths PHP can access. If SELinux or AppArmor is enabled, the file may also need the correct security context, not just standard permissions. After changing ownership, permissions, or server policy, retry the same absolute path with is_readable() before testing PHPMailer again.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Debugging PHPMailer Attachment Issues in PHP

When PHPMailer reports “Could not access file”, debug the attachment step separately from the email-sending step. The SMTP server is usually not involved yet; the failure commonly happens before delivery, when PHPMailer tries to read the local file passed to addAttachment() or addEmbeddedImage(). Start by logging the exact path your PHP code is using, then confirm that the same path exists and is readable from the PHP process running on the web server.

Check the path before adding the file

A practical debugging pattern is to validate the file immediately before calling addAttachment(). This helps distinguish a PHPMailer issue from a filesystem issue. For example, if a user uploads an invoice and you later attach it, inspect the resolved path, existence, file type, and readability before PHPMailer receives it.

$filePath = __DIR__ . '/uploads/invoice.pdf';

if (!file_exists($filePath)) {
error_log('Attachment missing: ' . $filePath);
} elseif (!is_file($filePath)) {
error_log('Attachment path is not a file: ' . $filePath);
} elseif (!is_readable($filePath)) {
error_log('Attachment not readable: ' . $filePath);
} else {
$mail->addAttachment($filePath, 'invoice.pdf');
}

If this check fails, PHPMailer is only exposing the underlying problem. If it passes but PHPMailer still fails, inspect whether the path changes between the check and the attachment call, whether the file is deleted by cleanup code, or whether a temporary upload file is being referenced after the request lifecycle has moved on.

Enable PHPMailer diagnostics

For mail transport problems, PHPMailer can emit SMTP debug output, but attachment file access errors may occur before SMTP communication. Still, enabling exceptions and capturing errors gives a clearer failure point. Use a try/catch block around the attachment and send process, and log the exception message together with the attachment path.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$mail = new PHPMailer(true);

try {
$attachment = realpath(__DIR__ . '/uploads/report.pdf');

if ($attachment === false || !is_readable($attachment)) {
throw new RuntimeException('Attachment cannot be read');
}

$mail->addAttachment($attachment, 'report.pdf');

$mail->isSMTP();
$mail->SMTPDebug = 2;
$mail->Debugoutput = 'error_log';

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

$mail->send();
} catch (Exception $e) {
error_log('PHPMailer error: ' . $mail->ErrorInfo);
} catch (RuntimeException $e) {
error_log($e->getMessage() . ': ' . ($attachment ?? 'unresolved path'));
}

Compare CLI and web server behavior

A common trap is testing a script from the command line and assuming it will behave the same through Apache, Nginx, PHP-FPM, or a hosting control panel. The CLI user may be different from the web server user, and the working directory may also differ. Log getcwd(), __DIR__, and the resolved attachment path during a real web request. If CLI works but the browser fails, focus on ownership, permissions, PHP-FPM pool users, open_basedir restrictions, and paths that only exist in the CLI environment.

  • Relative path mismatch: uploads/file.pdf may resolve differently depending on the entry script.
  • Temporary upload issue: files in $_FILES['tmp_name'] should be attached or moved before the request ends.
  • Hosting isolation: shared hosting may block access outside the account directory.
  • Case-sensitive filenames: Invoice.pdf and invoice.pdf are different on many Linux servers.
  • Symlink restrictions: a symlinked attachment may point to a location PHP cannot read.

For embedded images, apply the same checks before calling addEmbeddedImage(). The file must be accessible on the server filesystem; a browser URL such as https://example.com/logo.png is not a local readable path for PHPMailer. Download it first or reference the actual server path, such as /home/account/public_html/assets/logo.png. Once the path is absolute, the file exists, and the PHP process can read it, PHPMailer attachment errors usually disappear.

Frequently Asked Questions

How do I know which file path PHPMailer is actually trying to attach?

Before calling addAttachment(), print or log the full path you are passing to PHPMailer. Use checks like file_exists($path), is_readable($path), and realpath($path) to confirm PHP can see the file. If realpath() returns false, the path is wrong or the file is not accessible from the current PHP process.

Should I use a relative path or an absolute path with addAttachment()?

An absolute path is usually safer because relative paths depend on the script’s current working directory, which may not be the same as the file’s location. For example, use something like __DIR__ . '/uploads/invoice.pdf' instead of just 'uploads/invoice.pdf'. This makes the attachment path predictable even if the script is included from another file or run from a different directory.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does file_exists() return true but PHPMailer still says “Could not access file”?

This often happens when the file exists but PHP cannot read it due to permissions, ownership, or restrictions such as open_basedir. Check is_readable($path) as well as file_exists($path). On Linux hosting, the file and its parent directories must be readable by the web server user, such as www-data, apache, or the account user used by PHP-FPM.

What permissions should attachment files and folders have on a web server?

In most cases, folders should be executable and readable by the PHP process, commonly 755, and files should be readable, commonly 644. Avoid using 777 unless your host specifically requires it, because it can create security risks. Also check ownership, because correct numeric permissions may still fail if the file belongs to another user that PHP cannot access.

Can shared hosting or server settings cause this error even when my code is correct?

Yes, shared hosting often restricts which directories PHP can access using settings like open_basedir, disabled functions, jailed file systems, or separate users for FTP and PHP. Files uploaded outside the allowed web or account directory may be invisible to PHPMailer. If local path checks fail unexpectedly, check your hosting control panel error logs or ask the host which absolute paths PHP is allowed to read.

Bottom Line

PHPMailer’s “Could not access file” error almost always means PHP cannot read the file you passed to addAttachment() or an embedded image method. Check the real filesystem path, confirm the file exists with file_exists(), use an absolute path when possible, and make sure the web server user has permission to read it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If the path and permissions look correct, review hosting restrictions such as open_basedir, temporary upload handling, symlinks, chrooted environments, or files stored outside the allowed directory. Once you verify the exact path PHP sees and test readability before calling PHPMailer, the fix is usually straightforward.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.