An error occurred in the upload. Please try again later — 10 ways to fix it

A frustrated WordPress site owner shouting at a monitor after an upload error.HTTP 413 · upload failed

You are mid-upload — a new image, a plugin, a theme ZIP — and WordPress stops you with a flat, unhelpful line: “An error occurred in the upload. Please try again later.” No file name, no size, no cause. The message is generic on purpose, but the fixes are not.

The good news: this error almost always traces back to one of ten predictable causes, from a browser hiccup to PHP limits to how your host stores files. This guide walks each one in the order a professional would check them — cheapest and safest first.

TL;DR

Retry the same file in Media Library › Add New first. If one small JPG uploads but a large file fails, it is almost certainly PHP limits (upload_max_filesize / post_max_size). If every file fails, suspect a plugin, the uploads folder, or a host block. Scan your site free if unfamiliar files appeared — upload failures sometimes follow a hack.

Check the Media Library first

Before you touch server settings, confirm what actually failed. Open Media Library › Add New and upload the exact same file there instead of inside a post, page builder, or form.

Searching the WordPress Media Library for the just-uploaded test file, showing one matching item.
Search the Media Library for the file after a retry — if it appears, the upload itself worked.

This one test splits the problem in two: a bad file is a completely different issue from a broken upload path. If the file lands in the Media Library after a refresh, the upload worked and the response failed — a browser or session problem, not a server one.

Before changing settings

Do not start changing PHP or hosting settings until you know which half of the problem you have. Guessing here is how a two-minute fix becomes a two-hour one.

Diagnose and fix the upload error

Use this table to choose the next branch. It is intentionally short: the goal is direction, not a full server audit.

What you seeStart here
File appears after refreshUpload worked, response failed. Check browser/session behaviour.
Only one file failsRename, compress, convert, or re-export it. Test a plain JPG/PNG.
Every file failsCheck plugins, theme, the uploads folder, PHP limits, and security blocks.
Only large files failCompare upload_max_filesize, post_max_size, memory and timeouts.
Network shows 403, 413 or 5xxCollect the request details and involve your host if the cause is not obvious.
WordPress Site Health Status overview showing recommended improvements.
Tools › Site Health is the fastest way to see configuration and server issues WordPress already knows about.

Fix browser and file issues

This is the safest branch and the one most people should finish before touching plugins or hosting settings.

The WordPress block editor with the media inserter open, retrying the upload inside a draft post.
Retrying inside the editor’s media inserter — if it fails here but works in Media Library, the editor or its blocks are involved.
  • Hard-refresh, then retry in a private/incognito window to rule out cache and extensions.
  • Compress or resize a large image before retrying.
  • Convert unusual images to JPG or PNG for the test.
  • Re-export if the file may be corrupted, then upload from Add New.
File type safety

If WordPress says the file type “is not permitted for security reasons,” treat that as a separate issue. Do not casually allow SVGs, executables or scripts just to push one upload through.

Check plugins and themes

If the same small test file fails, look for code that changed the upload path. Image-optimisation plugins, security plugins, media tools, page builders and WooCommerce extensions are common suspects — especially right after an update.

WordPress Plugins screen with installed plugins, used to deactivate suspects one at a time.
Deactivate suspects on staging, not live — a two-minute test can break checkout or scheduled jobs.
  • Deactivate the newest or most relevant suspect plugin, then retry.
  • If nothing changes, deactivate plugins briefly and reactivate one by one.
  • Switch temporarily to a default theme to rule out theme-level upload handling.

Fix uploads, permissions, and storage

WordPress needs a writable place to put files, usually the wp-content/uploads folder. If that folder is missing, full, blocked, or owned by the wrong server user, uploads fail with the same generic message.

Fix ownership and permissions — do not make a suspicious site easier to write to. On most Linux hosts, directories should be 755 and files 644, owned by the web-server user:

Reset uploads permissionsBASH
# directories 755, files 644
find wp-content/uploads -type d -exec chmod 755 {} \;
find wp-content/uploads -type f -exec chmod 644 {} \;

# hand ownership back to the web server
chown -R www-data:www-data wp-content/uploads
  • Confirm the uploads folder exists and WordPress is using the expected path.
  • Check whether the hosting account is out of disk space.
  • Ask the host to verify ownership if the issue began after a migration or restore.

Check PHP limits

If small files upload but large files fail, look at PHP and hosting limits. The max upload size WordPress shows is a clue, not the whole truth — a control panel can show one value while the active runtime uses another after a PHP version change or a stray .user.ini.

SettingWhy it matters
upload_max_filesizeMust be larger than the uploaded file.
post_max_sizeMust be equal to or higher than upload_max_filesize.
memory_limitMust leave enough room for image processing.
max_execution_timeMust allow enough time for slow or large uploads.
max_input_timeCan stop slow uploads before PHP finishes receiving input.

Where this goes wrong: someone raises upload_max_filesize to 256 MB but leaves post_max_size at 64 MB, so a 100 MB upload still fails even though one setting looks generous. Raise them together:

php.iniINI
upload_max_filesize = 256M
post_max_size       = 256M
memory_limit        = 512M
max_execution_time  = 300
max_input_time      = 300
Verify the live PHP limits

Check Tools › Site Health › Info › Server for the values PHP is actually using. If your host panel disagrees with WordPress, ask which PHP configuration is live — changes may belong in .user.ini, not php.ini.

WordPress Site Health, Info, Server panel listing PHP version, upload max filesize and post max size.
Site Health → Info → Server reports the limits the live PHP runtime is really enforcing.

Check image processing

WordPress accepting a file type and the server being able to process it are two different things. Even when the upload transfers cleanly, PHP still has to read the image, pull its metadata, and generate the thumbnail and intermediate sizes. If the image library is missing or under-resourced, that step fails and you get the same generic error.

  • Confirm an image library is active — Imagick or GD — under Site Health › Info › Media Handling.
  • Very large pixel dimensions can exhaust memory_limit during resizing even when the file’s KB size is small.
  • Re-export unusual formats (HEIC, CMYK, progressive or 16-bit) to a standard sRGB JPG or PNG and retry.
WordPress Media Settings showing thumbnail, medium and large image size dimensions.
The sizes under Settings › Media are regenerated on every upload — each one is another chance for image processing to run out of memory.

Inspect the failed request

When the cause is not obvious, open your browser’s Network tab, reproduce the upload, and read the request to async-upload.php. The status code points you straight at the culprit — here is what a clean (200) request looks like, with everything sensitive stripped out:

NetworkSanitized upload request

Request

POST /wp-admin/async-upload.php

200
Status200 OK
Response typetext/plain
Visible detailsMethod, path, status, and response type only
Hidden for privacyHeaders, cookies, nonces, query strings, and full site URL

A failed upload shows a different code — and each one narrows the cause immediately:

  • 413 Payload Too Large — the server rejected the size before PHP saw it (often Nginx client_max_body_size).
  • 403 Forbidden — a firewall, ModSecurity rule, or security plugin is blocking the request.
  • 5xx — a server-side crash; check PHP error logs and memory before retrying.

Choose a recovery path

You can chase every branch above by hand, or let a plugin diagnose the common causes for you. Here is the honest trade-off:

Fix it manually

Free · your time

  • Full control over every setting
  • Requires server access & PHP know-how
  • Easy to miss a security-driven block
  • No safety net if the site is compromised
Recommended

Fix it with MalCare

Free scan · one click

  • Rules out malware behind the failure
  • Flags firewall & security-plugin blocks
  • Runs off-server — no slowdown
  • Cleanup on hand if it was a hack

Contact your host with evidence

If you have ruled out the browser, the file, plugins, permissions, PHP limits, and image processing, the block is likely at the server or network edge — somewhere you cannot see from inside WordPress. Open a support ticket, but make it easy to act on. Send specifics, not “uploads are broken”:

  • The exact file, its size and type, and the timestamp of a failed attempt.
  • The HTTP status from the Network tab (403, 413, 5xx) and any request ID.
  • Ask them to check server error logs, ModSecurity/WAF rules, and any CDN or reverse-proxy body-size limit for that timestamp.

Prevent repeat upload errors

Once uploads work again, a few habits keep the error from coming back:

  • Keep post_max_sizeupload_max_filesize whenever you change either.
  • Compress images before upload so you are not fighting limits daily.
  • Test plugin and PHP updates on staging before they touch the live upload path.

Frequently asked questions

The message is deliberately generic so it does not leak server details to attackers. The actual cause lives in the failed network request and your PHP error log.
Mismatched PHP limits — usually post_max_size set lower than upload_max_filesize, or an Nginx client_max_body_size the control panel never mentions.
On most hosts the live values belong in .user.ini, not php.ini. Confirm what PHP is actually using in Tools › Site Health › Info › Server before and after the change.
No — that is a separate MIME-type block. Do not casually allow SVGs, executables or scripts just to push one upload through; treat it as its own security decision.
Occasionally. If unfamiliar files appeared in wp-content/uploads or a security tool flagged activity you do not recognise, scan before loosening permissions.

Shivani enjoys crafting guides that make every aspect of using WordPress simple and easy to follow. When she's not glued to her laptop, you can find her buried in a good book or occasionally, painting.