uwsgi + nginx + flask: upstream prematurely closed

user299709 picture user299709 · Dec 10, 2014 · Viewed 27k times · Source

I created an endpoint on my flask which generates a spreadsheet from a database query (remote db) and then sends it as a download in the browser. Flask doesn't throw any errors. Uwsgi doesn't complain.

But when I check nginx's error.log I see a lot of

2014/12/10 05:06:24 [error] 14084#0: *239436 upstream prematurely closed connection while reading response header from upstream, client: 34.34.34.34, server: me.com, request: "GET /download/export.csv HTTP/1.1", upstream: "uwsgi://0.0.0.0:5002", host: "me.com", referrer: "https://me.com/download/export.csv"

I deploy the uwsgi like

uwsgi --socket 0.0.0.0:5002 --buffer-size=32768 --module server --callab app

my nginx config:

server {
     listen 80;
     merge_slashes off;
     server_name me.com www.me.cpm;

     location / { try_files $uri @app; }
       location @app {
          include uwsgi_params;
          uwsgi_pass 0.0.0.0:5002;
          uwsgi_buffer_size 32k;
          uwsgi_buffers 8 32k;
          uwsgi_busy_buffers_size 32k;
     }

}

server {
      listen 443;
      merge_slashes off;
      server_name me.com www.me.com;

    location / { try_files $uri @app; }
       location @app {
          include uwsgi_params;
          uwsgi_pass 0.0.0.0:5002;
          uwsgi_buffer_size 32k;
          uwsgi_buffers 8 32k;
          uwsgi_busy_buffers_size 32k;
       }
}

Is this an nginx or uwsgi issue, or both?

Answer

Ivan Ogai picture Ivan Ogai · Feb 14, 2019

As mentioned by @mahdix, the error can be caused by Nginx sending a request with the uwsgi protocol while uwsgi is listening on that port for http packets.

When in the Nginx config you have something like:

upstream org_app {
    server              10.0.9.79:9597;
}
location / {
    include         uwsgi_params;
    uwsgi_pass      org_app;
}

Nginx will use the uwsgi protocol. But if in uwsgi.ini you have something like (or its equivalent in the command line):

http-socket=:9597

uwsgi will speak http, and the error mentioned in the question appears. See native HTTP support.

A possible fix is to have instead:

socket=:9597

In which case Nginx and uwsgi will communicate with each other using the uwsgi protocol over a TCP connection.

Side note: if Nginx and uwsgi are in the same node, a Unix socket will be faster than TCP. See using Unix sockets instead of ports.