"The link you followed has expired." appears in WordPress when you upload a theme or plugin zip, or submit an admin form, and WordPress rejects the request. The text suggests a timeout, but in most cases the real cause is a size limit: the upload was larger than PHP allows, so PHP discarded the form data, and WordPress could not find the security token it expected.
Knowing that changes how you fix it. You raise limits first, and only then look at expired sessions and caching.
Why it happens
WordPress protects admin actions with nonces, one-time-style tokens tied to your login. Every admin form includes one. On submit, WordPress checks it, and if it is missing or invalid, it stops with this message (or "Are you sure you want to do this?").
Two situations produce a missing or invalid token:
- The request body exceeded
post_max_size. PHP then provides empty$_POSTand$_FILES. The nonce field was part of the discarded data, so the check fails. This is the classic cause for theme and plugin uploads. - The nonce really did expire. Nonces live for a limited period, 12 to 24 hours with the default filter. A form left open overnight, or served from a page cache, fails.
Step 1: check your PHP upload limits
In the dashboard, open Media, Add New and read "Maximum upload file size". WordPress shows the lower of upload_max_filesize and post_max_size. Compare it with the size of your zip. Many large premium themes are well above the common 2 MB or 8 MB defaults.
From the command line, check the values PHP-FPM uses, not just the CLI:
php -i | grep -E "^(upload_max_filesize|post_max_size|memory_limit|max_execution_time)"
If the CLI and the web server use different php.ini files, put a temporary phpinfo() page on the site, read the values, then delete the page.
Step 2: raise the limits
Use whichever applies to your host.
php.ini or a .user.ini file in the site root (PHP-FPM, CGI):
upload_max_filesize = 64M
post_max_size = 72M
memory_limit = 256M
max_execution_time = 300
post_max_size should be larger than upload_max_filesize. .user.ini changes can take a few minutes to apply, because PHP caches them (the user_ini.cache_ttl setting, 300 seconds by default).
Apache with mod_php in .htaccess:
php_value upload_max_filesize 64M
php_value post_max_size 72M
Those php_value lines cause a 500 error under PHP-FPM, since the module is not present. Use .user.ini there.
nginx also needs client_max_body_size, or you will see a 413 instead; see nginx 413 Request Entity Too Large. Reload PHP-FPM and nginx after changes.
Step 3: if raising limits is not possible
Install the theme or plugin manually. Unzip it locally and upload the folder with SFTP to wp-content/themes/ or wp-content/plugins/, then activate it in the dashboard. Or use WP-CLI on the server:
wp theme install /tmp/theme.zip --activate
wp plugin install /tmp/plugin.zip --activate
Neither path touches the browser upload limit. For the specific "exceeds the maximum upload size" message in the media library, see upload exceeds upload_max_filesize.
Step 4: if the limits are fine, suspect a stale nonce
- Reload the page you came from, then repeat the action. Do not use the browser back button.
- Log out and back in. If the login cookie is broken, see cookies are blocked.
- Check whether a page cache or CDN caches admin pages. Admin and login pages should never be cached; confirm with the HTTP Header Checker that
/wp-admin/returnsCache-Control: no-cachestyle headers and noHITcache header. - If the form is a front-end form in a plugin, exclude that page from caching, since a cached nonce goes stale.
- Disable security or optimization plugins temporarily; the method is in plugin conflict troubleshooting.
- Check that the server clock is correct. A badly wrong system time distorts nonce validity.
How to verify
Upload a small zip first, then the large one. Watch the Network tab in your browser developer tools: the POST should return 302 or 200, not an HTTP error. The Cookie Checker can show how your session cookies are set if logins are part of the problem.
अगले कदम
- Read WordPress memory limit exhausted fix if the upload gets further and then fails.
- Review Updating failed: not a valid JSON response for editor-side saves.
- Run a वेबसाइट हेल्थ चेक.
- Monitor the login page with the अपटाइम मॉनिटर.
सामान्य प्रश्न
Does the link really expire after a time?
Only if you leave the form open for many hours. Most reports of this message come from uploads larger than PHP allows.
Why is there no clear size error?
PHP drops the entire request body when it exceeds post_max_size, so WordPress never sees the file or the nonce and can only report the token failure.
Is it safe to raise post_max_size?
Yes, within reason. Larger values let any visitor to your upload endpoints send bigger bodies, so keep them only as large as you need.
Does this affect multisite differently?
Multisite also has a network-level upload size setting. The effective limit is the smallest of the network setting and the PHP values.
Get notified when this fix updates
Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.
यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.