Tegano Masinde
Report an issue
All case studies
Own test serverLinux · Nginx · PHP-FPM

Photos Wouldn't Upload: A Size Limit Hiding in Two Places

A vague "HTTP error" in WordPress traced to a one-megabyte limit on the web server, with a second limit waiting behind it in PHP.

Illustration of a WordPress image upload failing with HTTP error 413
Not a screenshot from a client site.

Adding a photo in the WordPress media library fails with a vague "HTTP error". Small images upload fine. Larger ones do not. Nothing on the site was changed recently, which makes a broken plugin unlikely. I worked this through on my own LEMP test server (Linux, Nginx, MariaDB, PHP).

  1. Test with different file sizesFiles under about 1 MB uploaded and larger ones failed. A failure that depends on size points to a size limit, not a bug in a plugin or theme.
  2. Check what the browser is toldIn the browser's network tab the upload request ends with status 413, "Request Entity Too Large". The Nginx error log then names the cause: the server turned the file away before PHP ever saw it. Nginx rejects any request body over client_max_body_size, which defaults to 1 MB.
    Nginx error log (typical message)
    client intended to send too large body
  3. Look for overrides before changing anythingA value in a server block beats the one in nginx.conf, so I searched every config file first.
    Find existing limits
    grep -rn client_max_body_size /etc/nginx/
  4. Fix both layers, not just oneRaising only the Nginx limit would move the failure one layer down, because PHP has its own limits. So I raised the Nginx limit, checked the config and reloaded it, then raised the two PHP limits and restarted PHP-FPM. A reload of Nginx alone does not apply PHP settings. The values below are examples. The right size depends on what the site needs.
    Nginx (server block)
    client_max_body_size 64M;
    PHP (php.ini)
    ; post_max_size must be at least as large as upload_max_filesize
    upload_max_filesize = 64M
    post_max_size = 72M
    Apply the changes
    sudo nginx -t && sudo systemctl reload nginx
    sudo systemctl restart php-fpm
  5. Test it the way a user wouldI uploaded a large photo through the media library, exactly as a site owner would, and confirmed the new limit under Site Health in WordPress. Then I wrote down every value changed and where, so nobody has to rediscover it later.

Two more from the same test server:

  • Locked out after switching to HTTPS too early. The site's address settings had been changed to HTTPS before the certificate and redirects were ready, which locked the admin out. I restored access from the command line with WP-CLI by correcting the home and site URLs, then made the switch in the right order.
    Restore the working address with WP-CLI
    wp option update home 'http://example.local'
    wp option update siteurl 'http://example.local'
  • "The site is down", but only for me. Requests sent with curl and an explicit Host header proved Nginx was routing each domain correctly. The real cause was the browser remembering an old secure-connection rule (HSTS), so nothing needed changing on the server.
    Test a domain directly, bypassing the browser
    curl -I -H 'Host: example.local' http://127.0.0.1/
← Previous caseAll case studies