Web Server Intermediate

Troubleshooting Nginx 413 Request Entity Too Large on WSL2 Ubuntu

Fix Nginx 413 errors on WSL2 Ubuntu by increasing client_max_body_size. This guide covers common causes and step-by-step configuration adjustments for successful file uploads.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Fix Nginx 413 errors on WSL2 Ubuntu by increasing client_max_body_size. This guide covers common causes and step-by-step configuration adjustments for successful file uploads.

When working with web applications in a development or staging environment on Windows Subsystem for Linux 2 (WSL2), you might encounter the "413 Request Entity Too Large" error. This typically occurs when your web application, served by Nginx, attempts to handle file uploads or large POST requests that exceed Nginx's default size limits. This guide provides a highly technical, accurate, and actionable resolution for this common issue within your WSL2 Ubuntu environment.

Symptom & Error Signature

Users experiencing this issue will typically encounter one of the following symptoms:

  1. Browser Error Page: The web browser displays an HTTP 413 Request Entity Too Large error page directly from Nginx, or a custom error page from your application if it catches the 413 status.
  2. Application Failure: The web application reports a "file upload failed" or similar error without a specific HTTP status code, but the underlying cause is an Nginx refusal.

The most definitive signature of this problem is found in the Nginx error logs. You can monitor these logs in your WSL2 Ubuntu instance:

sudo tail -f /var/log/nginx/error.log

You will observe log entries similar to this when the error occurs:

2024/03/10 10:30:45 [error] 1234#1234: *5 client intended to send too large body: 1234567 bytes, client: 172.18.0.1, server: example.com, request: "POST /api/upload HTTP/1.1", host: "example.com"

The key phrase client intended to send too large body directly points to Nginx's client_max_body_size directive.

Root Cause Analysis

The 413 Request Entity Too Large HTTP status code is returned by Nginx when the size of the client's request body exceeds the configured limit on the server. By default, Nginx sets the client_max_body_size directive to 1 megabyte (1m).

This limit is a crucial security feature designed to prevent various forms of denial-of-service (DoS) attacks, such as buffer overflows or resource exhaustion caused by malicious clients sending excessively large requests. When a request's content length (e.g., an uploaded file, large JSON payload in a POST request) surpasses this 1m threshold, Nginx will immediately terminate the connection and return the 413 error without passing the request to the upstream application server (like PHP-FPM, Node.js, Python WSGI, etc.).

In the context of WSL2, the Nginx instance runs within your Ubuntu distribution, completely isolated from the Windows host's file system and network stack, except for the necessary port forwarding. Therefore, troubleshooting involves modifying the Nginx configuration within the WSL2 Ubuntu environment, just as you would on a standalone Linux server.

It's important to note that if your application uses a language runtime (e.g., PHP-FPM), it might also have its own upload size limits (upload_max_filesize, post_max_size in PHP). These upstream limits must be equal to or greater than Nginx's client_max_body_size for the upload to succeed end-to-end. Nginx acts as the first line of defense; if it allows the request, the application server's limits then come into play.

Step-by-Step Resolution

To resolve the Nginx 413 error, you need to increase the client_max_body_size directive in your Nginx configuration.

1. Identify the Nginx Configuration File

Nginx configurations can be spread across multiple files. You need to identify where to place the client_max_body_size directive. Common locations include:

  • /etc/nginx/nginx.conf: The main Nginx configuration file. Directives placed in the http block here apply globally.
  • /etc/nginx/conf.d/*.conf: Files in this directory are typically included by nginx.conf and can contain server or http blocks.
  • /etc/nginx/sites-available/your_site.conf: Virtual host configuration files, usually symlinked to /etc/nginx/sites-enabled/. Directives placed in the server or location block here apply to a specific site or path.

To find where client_max_body_size might already be set, or to choose the best place for it, you can use grep:

sudo grep -r "client_max_body_size" /etc/nginx/

You can also test your Nginx configuration to see which files are loaded:

sudo nginx -t

This command will output the path to your main nginx.conf file, which you can then inspect for include directives.

2. Modify the Nginx Configuration

Edit the appropriate Nginx configuration file using your preferred text editor (e.g., nano or vim).

Option A: Apply Globally (recommended for development environments) Edit /etc/nginx/nginx.conf and add client_max_body_size inside the http block.

sudo nano /etc/nginx/nginx.conf

Locate the http { ... } block and add the directive. For example, to allow uploads up to 20MB:

http {
    # ... existing directives ...

    client_max_body_size 20M; # Increase Nginx upload limit to 20MB

    # ... other directives ...
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Option B: Apply per Server Block (for specific virtual hosts) If you want to apply the limit to a specific virtual host, edit its configuration file, typically located in /etc/nginx/sites-available/.

sudo nano /etc/nginx/sites-available/your_site.conf

Add the client_max_body_size directive inside the server { ... } block:

server {
    listen 80;
    server_name example.com www.example.com;

    client_max_body_size 20M; # Increase Nginx upload limit for this server

    root /var/www/example.com/public;
    index index.php index.html index.htm;

    # ... other directives ...
}

Option C: Apply per Location Block (for specific URLs) You can also apply the limit to a specific URL path within a server block, useful if only certain endpoints handle large uploads.

server {
    # ... existing directives ...

    location /api/upload {
        client_max_body_size 50M; # Allow 50MB for this specific upload endpoint
        # ... other location-specific directives ...
    }

    location / {
        # General settings, maybe a lower default client_max_body_size if not specified in server block
        # client_max_body_size 5M;
        # ...
    }
}

In the examples above, 20M represents 20 megabytes. You can use K for kilobytes or G for gigabytes. Choose a value that accommodates your application's largest expected uploads, ensuring it's reasonable.

Setting client_max_body_size to an excessively large value (e.g., 0 for unlimited) can expose your server to potential denial-of-service attacks. Attackers could flood your server with extremely large requests, consuming resources and potentially crashing your application or Nginx. Always set a practical and necessary limit.

3. Test Nginx Configuration Syntax

Before restarting Nginx, it's crucial to test the syntax of your configuration changes to avoid service disruption.

sudo nginx -t

A successful test will output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If there are any errors, Nginx will provide details about the location of the syntax error. Correct them before proceeding.

Do not skip this step! An invalid configuration file will prevent Nginx from starting or restarting, taking your web server offline.

4. Restart Nginx Service

After verifying the configuration, restart the Nginx service to apply the changes:

sudo systemctl restart nginx

Verify that Nginx has restarted successfully:

sudo systemctl status nginx

You should see output indicating active (running).

5. (Optional but Recommended) Adjust PHP-FPM Configuration

If your web application uses PHP (e.g., WordPress, Laravel, Symfony) and handles file uploads, you must also adjust PHP's upload limits. PHP has its own directives that control maximum file sizes for uploads and POST requests.

  1. Identify PHP version and php.ini location: To find your active php.ini file for the FPM SAPI:

    php -i | grep "Loaded Configuration File"
    

    Typically, for PHP 8.1 running with FPM, the file will be /etc/php/8.1/fpm/php.ini.

  2. Edit php.ini: Open the identified php.ini file for editing:

    sudo nano /etc/php/8.1/fpm/php.ini # Replace 8.1 with your PHP version
    
  3. Modify directives: Find and adjust the following directives to match or exceed your Nginx client_max_body_size:

    upload_max_filesize = 20M
    post_max_size = 20M
    memory_limit = 128M # Ensure this is also sufficient for large POST requests
    

    post_max_size must be equal to or greater than upload_max_filesize. Both of these values should be equal to or greater than the client_max_body_size you set in Nginx. If Nginx allows a 20MB request, but PHP only allows 10MB, the request will still fail at the PHP level.

  4. Restart PHP-FPM service: After saving changes to php.ini, restart your PHP-FPM service to apply them:

    sudo systemctl restart php8.1-fpm # Replace with your specific PHP-FPM service name
    

    The service name often includes the PHP version, e.g., php7.4-fpm, php8.0-fpm, php8.1-fpm, etc.

6. Test the Upload

Now, navigate to your web application and attempt the file upload or large POST request that previously failed. It should now succeed. If issues persist, re-check your Nginx and PHP-FPM (if applicable) logs for new error messages.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn →

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

Our Production Verification Guarantee

Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.