4

Running a Django 3 python 3.6 application with uwsgi & nginx is throwing too many of these! I have been spending way too much time trying to figure it out, so any help is welcome.

They are defintely not client disconnections. When looking online I find many uwsgi ini configurations and tried many of them, but to no avail. Most of them are HEAD requests from a country that has no business visiting the site, but there are many normal requests also getting this error. The messages look like this:

Uwsgi log:

Tue Sep 22 08:52:16 2020 - SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request / (ip x.xx.xx.xx) !!!
Tue Sep 22 08:52:16 2020 - uwsgi_response_writev_headers_and_body_do(): Broken pipe [core/writer.c line 306] during GET / (x.xx.xx.xx)
OSError: write error
[pid: 9852|app: 0|req: 6262/18763] x.xx.xx.xx () {46 vars in 981 bytes} [Tue Sep 22 08:52:15 2020] GET / => generated 0 bytes in 313 msecs (HTTP/1.1 200) 7 headers in 0 bytes (0 switches on core 0)

Nginx access log:

x.xx.xx.xx - - [22/Sep/2020:08:52:16 +0200] "GET / HTTP/1.1" 499 0 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 13_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Mobile/15E148 Safari/604.1"

It is not likely users are trying to escape the site in just these mere 313 msecs. This is the minimalist version currently running of the ini:

[uwsgi]
uid=www-data
gid=www-data
project=mysite
chdir=/home/myuser/releases/mysite-website/web
plugin=python36
wsgi-file=mysite/wsgi.py
daemonize=/home/myuser/logs/uwsgi/mysite-website.log
home=/home/myuser/releases/venv
processes = 1
enable-threads = true
socket=/var/run/uwsgi/app/mysite/socket.sock
pidfile=/var/run/uwsgi/app/mysite/project-masterpid
vacuum = true
touch-reload=/home/myuser/releases/mysite-website/web/mysite/wsgi.py

Nginx:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;

uwsgi_pass unix:///var/run/uwsgi/app/mysite/socket.sock;
include uwsgi_params;
uwsgi_param HTTPS on;
uwsgi_param UWSGI_SCHEME https;
uwsgi_read_timeout 60s;

uwsgi_params:

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
dross12
  • 41
  • 4
  • I might have solved what looks like a very similar issue adding the three options mentioned here in this answer to my .ini config file. May be of help to you as well: https://stackoverflow.com/questions/36156887/uwsgi-raises-oserror-write-error-during-large-request/45393743#45393743 – selmanbey Sep 29 '20 at 11:41

1 Answers1

3

In my experience these are legitimate disconnections, where the HTTP client (the browser) closes the connection and Nginx in turn closes the file descriptor uWSGI is writing a response to. See full write-up.

I can reliably replicate the issue by visiting any non-trivial Django page and hammering on the F5 (refresh) key a few times rapidly. That suggests that the errors are part of normal operation and aren't causing any negative user experience, so are likely safe to ignore.

It's certainly possible that these disconnections are caused by are badly behaving HTTP clients or automated attacks, but both of these are outside of your control.

To hide these exceptions in the logs you need all three of the following uWSGI settings, each corresponding to one of the error lines you listed.

ignore-sigpipe
ignore-write-errors
disable-write-exception

The disable-write-errors option will also prevent the errors being sent to a tool like Sentry if you're using something like that.

Ben Sturmfels
  • 1,303
  • 13
  • 22
  • This is not my experience. For me, I have a server making these requests, and I have traces showing they are sitting and waiting on the request. – Brian Peterson May 30 '23 at 20:39