Uploading Large Files to AWS Elastic Beanstalk Fails with HTTP 413 “Request Entity Too Large”

Whether you have a webapp deployed in Beanstalk or a REST API, you might have come across the HTTP 413 error when trying to POST or upload a file larger than 1 MB to it. This is because the Nginx server running in Beanstalk is configured to accept no more that 1 MB of data in a single request. This is done by setting the client_max_body_size parameter to 1 MB. All you have to do to accept larger uploads, is to change this parameter. But how do you do that in a Beanstalk environment?

There are several ways to do this. Unfortunately, there have been instances when the technique documented in the official AWS documentation hasn’t worked for many (including me), so this post will cover all ways that have worked for people over the years. You’re encouraged to try out one or more of them till you get it right!

For environments based on Amazon Linux 2 (Java, Node.js, Go, Ruby (maybe), etc.), try this:

To extend the Elastic Beanstalk default nginx configuration, add .conf configuration files to a folder named .platform/nginx/conf.d/ in your application source bundle. The Elastic Beanstalk nginx configuration includes .conf files in this folder automatically.

β€” Extending Elastic Beanstalk Linux platforms
~/workspace/my-app/
|-- .platform
|   `-- nginx
|       `-- conf.d
|           `-- myconf.conf
`-- other source files

To override the Elastic Beanstalk default nginx configuration completely, include a configuration in your source bundle at .platform/nginx/nginx.conf:

β€” Extending Elastic Beanstalk Linux platforms
~/workspace/my-app/
|-- .platform
|   `-- nginx
|       `-- nginx.conf
`-- other source files

To increase the maximum upload size specifically, then create a file at .ebextensions/nginx/conf.d/proxy.conf setting the max body size to whatever size you would prefer:

client_max_body_size 50M;

Or create the Nginx config file directly. Create a .config file in the .ebextensions directory:

files:
    "/etc/nginx/conf.d/proxy.conf" :
        mode: "000755"
        owner: root
        group: root
        content: |
           client_max_body_size 50M;

This generates a proxy.conf file inside of the /etc/nginx/conf.d directory. The proxy.conf file simply contains the one liner client_max_body_size 50M; which does the trick. For some platforms, this file will be created during deployment, but then removed in a later deployment! The deployment progress is logged at /var/log/cfn-init.log, in case you need to troubleshoot. Look for the line “[DEBUG] Writing content to /etc/nginx/conf.d/proxy.conf” in the logs.

You might need to SSH into the instance & restart Nginx for the change to take effect: sudo service nginx reload or to be safe pgrep nginx && service nginx reload || true. Deployment will restart Nginx in most cases but if it doesn’t, do it manually. It was possible to do this using a container_command in earlier versions of Beanstalk but these days that just causes the deployment to fail. Rebuilding the environment will also pick up this change.

container_commands:
  01_reload_nginx:
    command: "service nginx reload"

For the sake of completeness, here are the Amazon Linux 1 instructions as well:

To extend Elastic Beanstalk’s default nginx configuration, add .conf configuration files to a folder named .ebextensions/nginx/conf.d/ in your application source bundle. Elastic Beanstalk’s nginx configuration includes .conf files in this folder automatically.

β€” Configuring the proxy on Amazon Linux AMI
~/workspace/my-app/
|-- .ebextensions
|   `-- nginx
|       `-- conf.d
|           `-- myconf.conf
`-- web.jar

To override Elastic Beanstalk’s default nginx configuration completely, include a configuration in your source bundle at .ebextensions/nginx/nginx.conf:

β€” Configuring the proxy on Amazon Linux AMI
~/workspace/my-app/
|-- .ebextensions
|   `-- nginx
|       `-- nginx.conf
`-- web.jar

If absolutely nothing else works, you can always SSH into the instance & take the matter into your own hands β€” bypass Beanstalk entirely & configure Nginx like you would in a normal EC2 server.

Create nginx.conf in .ebextensions/nginx/. SSH into an instance of your Beanstalk app, copy the contents of nginx.conf using cat /etc/nginx/nginx.conf & copying from the terminal. Paste the contents into the nginx.conf file in .ebextensions/nginx/ & modify the http directive to include client_max_body_size 50M;. Redeploy the app using eb deploy. You’ll see the following message during deployment:

INFO: Nginx configuration detected in the ‘.ebextensions/nginx’ directory. AWS Elastic Beanstalk will no longer manage the Nginx configuration for this environment.

No need to restart Nginx or rebuild the environment! But do ensure that .ebextensions did indeed get zipped into the deployment package, i.e., it isn’t ignored in .gitignore or .ebignore.

Here’s yet another example from AWS’s official Beanstalk examples:

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/enact/12_add_nginx_configuration.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      /bin/echo "client_max_body_size 50M;" > /etc/nginx/conf.d/proxy.conf
      /sbin/service nginx reload

Here’s the source β€” AWS Docs / Elastic Beanstalk Samples β€” GitHub.

All of the above is for the Nginx server. You can also change the proxy server to Apache in the Beanstalk configuration & use its LimitRequestBody directive to set the upload limit. For .NET apps, you must configure IIS’s web.config.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.