Resolved the issue. The issue is not particularly regarding Frappe Framework or NGINX or Gunicorn configuration. This particular error is occurring from Wekzeug which is a WSGI tool used in production setup.
Here I will try to explain how error got triggered, where it got triggered from, and how I solved it.
Below are the flow of events which triggered the error:
We have developed a custom doctype which has around 20 child tables. These child table may contain large number of rows. When I tried to save the record, then on site I got the dialogue box with message “File size exceeded the maximum allowed size of 50 MB“. Second, on browser console it was showing error coming from request.js file. This code is available at frappe/frappe/public/js/frappe/request.js at develop · frappe/frappe · GitHub
Above screenshot is from request.js file. So on frappe site it shows above dialogue box, in browser console tab it shows error coming from request.js and in network tab, it shows 413 error from NGINX. So first I tried with setting higher value for max file size in system settings, but this value is get picked while showing in the dialogue box. Second I tried with NGINX max_client_body_size. Third, I tried with higher configuration for gunicorn workers. But request was successfully processed by NGINX as there was no error log in NGINX. And my client body size was well below 1 MB.
As there was no error in bench, web, NGINX error logs, it confirmed that error is coming from somewhere else. As dialogue box was triggering from JS code, I thought that some python code is triggering the error and sending it to JS code which in turn popping up the dialogue box.
So it was the time to escape from the loop of suggested solutions from Google, every possible community out there and try some different approach. First I went through Frappe Documentation regarding production setup. There I saw werkzeug tool being setup in production environment. I gave it a try to find out werkzeug package in frappe setup. The werkzeug tool uses request.py to process the data coming in the request body. This file is located at bench/env/lib/python3.11/site-packages/werkzeug/wrappers.
This request.py file enforces various limitations on request body coming from client side.
The above screenshot is from request.py file where various limits are enforced. In latest werkzeug versions, they (not frappe) are enforcing these limits. In earlier versions there were no such limitations. One such limitation enforced with following variable:
max_form_memory_size: int | None = 500_000
This 500_000 converts into 500Kb. So when my client body size was exceeding 500Kb, werkzeug was triggering RequestEntityTooLarge error and sending it to request.js which then popping up the dialogue box with max file size and 413 NGINX error.
In earlier versions of werkzeug variable looked like below:
max_form_memory_size: int | None = None
So I had three options to solve this issue:
- Downgrade the Werkzeug version. This wasn’t feasible as there were other dependencies.
2.To directly the request.py file and remove 500Kb limitation. Though possible but it wasn’t the cleanest way to achieve it because making changes in the main file sometimes break the things up.
3.To override the variable value using _init_.py file in my custom file. This was the solution I adopted which ultimately resolved the issue. I added below lines in the _init_.py file of my custom app:
from werkzeug.wrappers import Request
Request.max_form_memory_size = None
So i