The operation takes longer than the timeout allows
CommonA report, an export, a bulk import or a large upload that genuinely needs more than the limit. Nothing is broken — a synchronous HTTP request is the wrong shape for the work.
Confirm
sudo grep 'upstream timed out' /var/log/nginx/error.log | tail -20
Timeouts clustered on one endpoint rather than spread across the application. A single slow route is a strong signal for this cause.
Fix
- Make it asynchronous. Accept the request, return 202 with a job identifier, and let the client poll or receive a callback. This is the real fix and it removes the class of problem.
- If it must stay synchronous, raise `proxy_read_timeout` for that route only rather than globally — a global raise removes the protection everywhere else.
location /api/export {
proxy_pass http://app;
proxy_read_timeout 300s; # this route only
}Scope it to the location. Raising the global timeout hides genuine slowness across the whole application.