Kubernetes
Nginx
Ingress Controller
Upload Limit
Troubleshooting

Kubernetes nginx ingress controller cannot upload size more than 1mb

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If file uploads through ingress fail around 1 MB, the ingress controller is usually enforcing NGINX's request-body limit. In practice this often shows up as HTTP 413 Payload Too Large, even though the backend application itself would happily accept larger files.

With the NGINX Ingress Controller, the fix is usually to raise the body-size limit either on the specific Ingress resource or globally through the controller configuration. If uploads still fail after that, the next suspects are the backend app, upstream proxy, or load balancer.

Why the Limit Appears

NGINX enforces a maximum client request body size. In ingress-nginx, that becomes part of the generated NGINX configuration for your route.

So the path is:

  • client sends a file upload
  • NGINX ingress receives it first
  • NGINX rejects it before the request reaches the service

That is why application logs can look normal while the browser still gets a 413.

Fix It Per Ingress

The usual ingress-nginx annotation is nginx.ingress.kubernetes.io/proxy-body-size:

yaml
1apiVersion: networking.k8s.io/v1
2kind: Ingress
3metadata:
4  name: upload-api
5  annotations:
6    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
7spec:
8  ingressClassName: nginx
9  rules:
10    - host: upload.example.com
11      http:
12        paths:
13          - path: /
14            pathType: Prefix
15            backend:
16              service:
17                name: upload-service
18                port:
19                  number: 80

After applying the updated manifest, the controller should regenerate the server configuration and allow larger bodies for that ingress.

Set a Global Default With the Controller ConfigMap

If many applications need a higher upload limit, set the controller-wide default instead of repeating the annotation everywhere:

yaml
1apiVersion: v1
2kind: ConfigMap
3metadata:
4  name: ingress-nginx-controller
5  namespace: ingress-nginx
6data:
7  proxy-body-size: "50m"

The exact ConfigMap name can vary by installation, so confirm it in your cluster before editing. This global setting is useful when most routes share similar upload requirements.

Verify the Change Actually Took Effect

After updating the Ingress or ConfigMap, verify the controller reloaded the configuration:

bash
kubectl describe ingress upload-api
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller

Then test with a file that is larger than the old limit but smaller than the new one.

If the request still fails immediately, check whether:

  • the annotation is on the correct Ingress resource
  • the request is hitting the intended ingress controller class
  • another proxy sits in front of ingress-nginx

Do Not Stop at Ingress

Raising the ingress limit is necessary only if ingress is the bottleneck. Your application or framework may have its own request-size limit too.

Common examples:

  • Express body-parser limits
  • Spring multipart limits
  • Django or reverse-proxy upload settings
  • cloud load balancer request caps

So if ingress is configured for 50m but the app still fails at 10m, the next limit is downstream.

Buffering and Resource Considerations

Larger uploads are not free. Big request bodies affect:

  • ingress pod memory use
  • temporary disk usage if buffering is enabled
  • request timeouts
  • denial-of-service exposure if limits are raised too far

That does not mean you should keep the limit tiny. It means you should set a realistic maximum based on the product requirement instead of using an arbitrarily huge value.

A Practical Debugging Sequence

When uploads fail, check in this order:

  1. Browser or client error code, especially 413
  2. Ingress annotation or ConfigMap body-size setting
  3. Controller logs
  4. Backend framework upload limits
  5. Any external proxy or load balancer in front of Kubernetes

That keeps the investigation moving layer by layer instead of changing several systems at once.

Common Pitfalls

The most common mistake is updating the wrong ingress resource or the wrong ingress class. In clusters with multiple controllers, an annotation only matters if the request is handled by that controller.

Another common issue is fixing ingress but forgetting the backend app has its own upload cap. That leads to a different failure later in the request path.

People also set the limit globally to a huge value without considering resource usage or abuse risk. That solves the symptom but can create a worse operational problem.

Finally, if you edit the controller ConfigMap, confirm the controller actually reloaded it. A configuration change that never became active helps nothing.

Summary

  • A 1 MB upload failure through ingress-nginx is usually the request-body limit at the NGINX layer.
  • Set nginx.ingress.kubernetes.io/proxy-body-size on the Ingress or proxy-body-size in the controller ConfigMap.
  • Verify the change took effect and test with a file between the old and new limits.
  • If uploads still fail, check backend framework limits and any proxies in front of ingress.
  • Raise the limit deliberately, because larger uploads also increase resource and abuse exposure.

Course illustration
Course illustration

All Rights Reserved.