WordPress The Link You Followed Has Expired
What Is This Error?
If you’ve ever tried to upload a plugin, theme, or large media file in WordPress and landed on “The link you followed has expired,” you’re not alone. Despite the confusing wording, this error has almost nothing to do with an actual link going stale. What it really means is that your server rejected the operation before WordPress could finish it — usually because a file exceeded a PHP size limit.
WordPress generates this screen as a fallback when an upload or admin action fails silently at the server level. PHP cuts off the request mid-stream, WordPress loses the response it was expecting, and the generic “link expired” message is the only thing left to display.
The good news: this is a configuration problem, not a bug or a security issue. A few targeted changes to your PHP settings will clear it up without touching any plugin or theme code.
Get free WordPress & AI tips
Join 500+ readers. No spam, unsubscribe anytime.
Why Does This Happen?
- upload_max_filesize is set too low: PHP enforces a hard cap on how large an uploaded file can be. If your file exceeds it, the upload dies silently and WordPress surfaces this error.
- post_max_size is smaller than upload_max_filesize: Uploads travel via HTTP POST requests. If post_max_size is lower than upload_max_filesize, even an “in-limit” file can fail because the POST body gets truncated first.
- PHP memory_limit is too restrictive: WordPress needs memory headroom to process and move an uploaded file. If it runs out mid-operation, the entire process collapses.
- max_execution_time is too short: Large file transfers take time. If PHP kills the script before the upload finishes, you’ll hit this error.
- Genuine nonce expiration (rare): WordPress uses nonces — one-time security tokens — for admin actions. If you left an admin page open for several hours without acting, the nonce may have actually expired. A simple page refresh fixes this specific case.
How to Fix It — Step by Step
-
Check your current PHP limits first. In your WordPress dashboard go to Tools → Site Health → Info → Server. Note the values for “PHP memory limit,” “Max upload size,” and “Max input time” before making any changes.
You should see: A table of server values. These are your baseline — compare them again after your edits to confirm the changes took effect.
-
Add overrides to wp-config.php (easiest method). Open
wp-config.phpin your site’s root directory and add these lines just above the/* That's all, stop editing! */comment:@ini_set('upload_max_size', '128M'); @ini_set('post_max_size', '128M'); @ini_set('memory_limit', '256M');You should see: No errors on your site after saving. Refresh Site Health to verify the new values appear.
-
Edit .htaccess (Apache servers only). If the wp-config.php method didn’t register, open the
.htaccessfile in your root directory and add:php_value upload_max_filesize 128M php_value post_max_size 128M php_value memory_limit 256M php_value max_execution_time 300You should see: Updated values in Site Health. If your site throws a 500 error instead, your server runs Nginx — remove these lines immediately and proceed to the next step.
-
Edit php.ini directly (most reliable method). If your host provides access to
php.ini, update these four directives:upload_max_filesize = 128M post_max_size = 128M memory_limit = 256M max_execution_time = 300You should see: New values confirmed in Site Health after saving. On cPanel hosts, look for the MultiPHP INI Editor to make these changes through the panel UI instead of a raw file.
-
Upload via FTP as a bypass. For plugins and themes, download the zip, extract it locally, and upload the folder directly to
/wp-content/plugins/or/wp-content/themes/using an FTP client. Then activate it from your WordPress dashboard.You should see: The plugin or theme appear in its respective admin list, ready to activate — no browser upload needed at all.
Common Mistakes When Fixing This
- Raising upload_max_filesize but ignoring post_max_size: Both values work together as a pair. If post_max_size stays lower than upload_max_filesize, uploads will still fail at the POST level. Always set post_max_size equal to or higher than upload_max_filesize.
- Adding PHP directives to .htaccess on an Nginx server: These directives are Apache-only. On Nginx they’re silently ignored — or worse, trigger a 500 error. Use php.ini or a user.ini file in your site’s root directory instead.
- Editing the wrong php.ini file: Shared hosts often run multiple PHP versions, each with its own php.ini. Editing one that isn’t active does nothing visible. Always verify your changes registered by rechecking Site Health after saving.
- Retrying the upload without confirming changes are live: The error will repeat identically until the underlying PHP limit is actually in effect. Don’t retry the upload until Site Health shows the new values.
Frequently Asked Questions
Is this error a sign that my site was hacked?
No. This error is a server configuration issue triggered by PHP limits — it has nothing to do with a security breach. Your site data is intact; a setting just needs adjusting.
Why does WordPress say “link expired” instead of “file too large”?
When PHP cuts off an upload at the server level, it doesn’t pass a meaningful error back to WordPress — it simply drops the request. WordPress interprets the missing response as an expired action and shows the closest generic message it has for a failed POST operation.
I made all the changes but the error still appears — what now?
Verify the values are actually live by checking Tools → Site Health → Info → Server. If the PHP limits still show the old numbers, your host is overriding your settings. Contact your hosting provider and ask them to raise upload_max_filesize, post_max_size, and memory_limit directly — many managed and cloud hosts require this to be done through their support team or a dedicated control panel option.
Can this happen during plugin updates, not just fresh installs?
Yes. Plugin update packages can be just as large as fresh installs, and they go through the exact same upload pipeline. The same PHP limit increases resolve update failures too.
