Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gunicorn 19.7.0 raises Socket Error! #1487

Closed
aalhour opened this issue Mar 19, 2017 · 27 comments
Closed

Gunicorn 19.7.0 raises Socket Error! #1487

aalhour opened this issue Mar 19, 2017 · 27 comments

Comments

@aalhour
Copy link

aalhour commented Mar 19, 2017

Hello guys,

I have been testing the performance of an application built with Flask, SQLAlchemy and gevent on Gunicorn==19.7.0 with wrk and it keeps raising Socket Errors, the issue disappears by downgrading to Gunicorn==19.6.0, here is the full stack trace:

[2017-03-20 00:46:39 +0100] [79068] [ERROR] Socket error processing request.
Traceback (most recent call last):
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/async.py", line 66, in handle
    six.reraise(*sys.exc_info())
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/six.py", line 625, in reraise
    raise value
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/async.py", line 56, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/ggevent.py", line 152, in handle_request
    super(GeventWorker, self).handle_request(*args)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/async.py", line 129, in handle_request
    six.reraise(*sys.exc_info())
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/six.py", line 625, in reraise
    raise value
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/async.py", line 115, in handle_request
    resp.write(item)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/http/wsgi.py", line 362, in write
    util.write(self.sock, arg, self.chunked)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/util.py", line 321, in write
    sock.sendall(data)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gevent-1.2.1-py3.6-macosx-10.12-x86_64.egg/gevent/_socket3.py", line 418, in sendall
    data_sent += self.send(data_memory[data_sent:], flags)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gevent-1.2.1-py3.6-macosx-10.12-x86_64.egg/gevent/_socket3.py", line 391, in send
    return _socket.socket.send(self._sock, data, flags)
OSError: [Errno 41] Protocol wrong type for socket

Full list of pip dependencies:

appdirs==1.4.3
bcrypt==3.1.3
cffi==1.9.1
click==6.7
Flask==0.12
Flask-Bcrypt==0.7.1
Flask-Compress==1.4.0
Flask-Login==0.4.0
Flask-Script==2.0.5
Flask-SQLAlchemy==2.2
gevent==1.2.1
greenlet==0.4.12
gunicorn==19.7.0
honcho==0.7.1
itsdangerous==0.24
Jinja2==2.9.5
MarkupSafe==1.0
packaging==16.8
psycogreen==1.0
psycopg2==2.7.1
pycparser==2.17
PyJWT==1.4.2
pyparsing==2.2.0
python-dateutil==2.6.0
requests==2.13.0
setproctitle==1.1.10
six==1.10.0
SQLAlchemy==1.1.6
Werkzeug==0.12.1

Commands:

  • Running the app: gunicorn -k gevent -w 18 sa7beh.app:app
  • Wrk command: wrk -c 3600 -t 2000 -d 60 <API URL>

Let me know if you need more information.

@benoitc
Copy link
Owner

benoitc commented Mar 20, 2017

can you try with #1483 ?

@aalhour
Copy link
Author

aalhour commented Mar 20, 2017

Hello @benoitc,

Thanks for your prompt reply.

I have checked out Gunicorn at the specified branch and commit in #1483 and installed it into the virtual environment. Unfortunately, the same error keeps reappearing.

[2017-03-20 19:06:03 +0100] [19819] [ERROR] Socket error processing request.
Traceback (most recent call last):
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/async.py", line 66, in handle
    six.reraise(*sys.exc_info())
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/six.py", line 625, in reraise
    raise value
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/async.py", line 56, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/ggevent.py", line 152, in handle_request
    super(GeventWorker, self).handle_request(*args)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/async.py", line 129, in handle_request
    six.reraise(*sys.exc_info())
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/six.py", line 625, in reraise
    raise value
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/workers/async.py", line 115, in handle_request
    resp.write(item)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/http/wsgi.py", line 361, in write
    util.write(self.sock, arg, self.chunked)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gunicorn-19.7.0-py3.6.egg/gunicorn/util.py", line 306, in write
    sock.sendall(data)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gevent-1.2.1-py3.6-macosx-10.12-x86_64.egg/gevent/_socket3.py", line 418, in sendall
    data_sent += self.send(data_memory[data_sent:], flags)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.6/site-packages/gevent-1.2.1-py3.6-macosx-10.12-x86_64.egg/gevent/_socket3.py", line 391, in send
    return _socket.socket.send(self._sock, data, flags)
OSError: [Errno 41] Protocol wrong type for socket

@jamadden
Copy link
Collaborator

Hi, gevent developer here. We recently had a somewhat similar issue come up with Python 2 sockets and SOCK_CLOEXEC that makes me wonder if there might be something going on at the gevent level. I primarily run on OS X and I haven't been able to reproduce this yet in a simplified example (not using gunicorn)...but I haven't tried that hard yet :) A few questions that might help narrow things down:

Correct me if I'm wrong, but you're using the default gunicorn listener configuration, so TCP, and not unix sockets?

You look to be on OS X 10.12 sierra?

Did you build gevent from source (looks that way) or did you install the binary egg from PyPI?

@jamadden
Copy link
Collaborator

jamadden commented Mar 20, 2017

I also can't reproduce using gunicorn 19.7.0 and the simplest possible app (on OS X 10.12, Python 3.6 from macports, using the gevent wheel from PyPI:

# app.py
def app(environ, start_response):
	start_response("200 OK", [('Content-Type', 'text/plain')])
	return [b"This is some text to stream"]
$ pip freeze
appdirs==1.4.3
gevent==1.2.1
greenlet==0.4.12
gunicorn==19.7.0
packaging==16.8
pyparsing==2.2.0
six==1.10.0
$ gunicorn -k gevent -w 18 app:app
[2017-03-20 13:23:25 -0500] [22810] [INFO] Starting gunicorn 19.7.0
[2017-03-20 13:23:25 -0500] [22810] [INFO] Listening at: http://127.0.0.1:8000 (22810)
[2017-03-20 13:23:25 -0500] [22810] [INFO] Using worker: gevent
...
$ http localhost:8000
HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: text/plain
Date: Mon, 20 Mar 2017 18:23:34 GMT
Server: gunicorn/19.7.0
Transfer-Encoding: chunked

This is some text to stream

EDIT: I also cannot reproduce using the python.org installed version of 3.6.0.

@aalhour
Copy link
Author

aalhour commented Mar 20, 2017

Hello @jamadden,

Thanks for trying to help. The error doesn't appear right after starting the app. It actually appears 5-10 times (probably for 5-10 requests) when I test the app with wrk which sends out 20K requests in a minute.

Regarding your questions, I am using Gunicorn with the standard configuration, I am binding it to 0.0.0.0:5000, worker class is gevent and my gunicorn configuration file sets the number of workers to (multiprocessing.cpu_count() * 2) + 1 which ends forking 18 processes including the master one. I have install gevent using pip via the pip -r requirements.txt command, you can find the complete list of dependencies above. And you guessed it right, I am on macOS Sierra 10.12.3.

I don't know what is causing the problem to be honest but I can reproduce it every single time I test the app with wrk, I just tried to downgrade my Python version (installed via pyenv) from v3.6.0 to v3.5.3 but kept Gunicorn's version at 19.7.0, and the problem persisted. However, by just downgrading the version of Gunicorn to 19.6.0, the problem stopped appearing at all, I ran different tests with wrk against different APIs that do touch the database, and the problem didn't appear. The following are the commands I tried to try smoke out the issue:

  • wrk -c 1000 -t 100 -d 60 http://localhost:5000/api/v1.0/users
  • wrk -c 3600 -t 2000 -d 60 http://localhost:5000/api/v1.0/users
  • wrk -c 3600 -t 2000 -d 120 http://localhost:5000/api/v1.0/users

The above 3 commands always reproduced the problem on Python 3.6.0.

Also, I mentioned in my first comment that the issue disappears when downgrading to Gunicorn==19.6.0, but it still shows up as long as my Python's version is 3.6.0. The issue only disappeared so far with the combination: Python==3.5.3 + Gunciron==19.6.0.

I hope the above information helped.

@aalhour
Copy link
Author

aalhour commented Mar 20, 2017

Hello @benoitc , @jamadden,

The issue looks to be even worse! I have just ran a longer test (5 minutes) with wrk and the issue appeared again. It doesn't look like downgrading Python and Gunicorn helped, they just made the issue take more time to appear. Here is the test command:

wrk -c 3600 -t 2000 -d 300 http://localhost:5000/api/v1.0/users

Here is how I am currently running Gunicorn:

gunicorn -k gevent -w 4 -b 0.0.0.0:5000 sa7beh.app:app > logs/sa7beh_app.log 2>&1

Here is what happens when I grep the log for errors:

$ grep "ERROR" logs/sa7beh_app.log
[2017-03-20 20:35:10 +0100] [39495] [ERROR] Socket error processing request.
[2017-03-20 20:35:11 +0100] [39496] [ERROR] Socket error processing request.
[2017-03-20 20:35:11 +0100] [39495] [ERROR] Socket error processing request.
[2017-03-20 20:35:11 +0100] [39494] [ERROR] Socket error processing request.
[2017-03-20 20:35:11 +0100] [39496] [ERROR] Socket error processing request.
[2017-03-20 20:35:11 +0100] [39494] [ERROR] Socket error processing request.
[2017-03-20 20:35:11 +0100] [39494] [ERROR] Socket error processing request.
[2017-03-20 20:35:11 +0100] [39494] [ERROR] Socket error processing request.
[2017-03-20 20:35:11 +0100] [39494] [ERROR] Socket error processing request.

All these 9 cases have the same traceback, here is a sample:

$ grep -A 30 "ERROR" logs/log_file.log 
[2017-03-20 20:35:10 +0100] [39495] [ERROR] Socket error processing request.
Traceback (most recent call last):
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gunicorn-19.6.0-py3.5.egg/gunicorn/workers/async.py", line 62, in handle
    six.reraise(*sys.exc_info())
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gunicorn-19.6.0-py3.5.egg/gunicorn/six.py", line 625, in reraise
    raise value
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gunicorn-19.6.0-py3.5.egg/gunicorn/workers/async.py", line 52, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gunicorn-19.6.0-py3.5.egg/gunicorn/workers/ggevent.py", line 152, in handle_request
    super(GeventWorker, self).handle_request(*args)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gunicorn-19.6.0-py3.5.egg/gunicorn/workers/async.py", line 125, in handle_request
    six.reraise(*sys.exc_info())
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gunicorn-19.6.0-py3.5.egg/gunicorn/six.py", line 625, in reraise
    raise value
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gunicorn-19.6.0-py3.5.egg/gunicorn/workers/async.py", line 111, in handle_request
    resp.write(item)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gunicorn-19.6.0-py3.5.egg/gunicorn/http/wsgi.py", line 362, in write
    util.write(self.sock, arg, self.chunked)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gunicorn-19.6.0-py3.5.egg/gunicorn/util.py", line 302, in write
    sock.sendall(data)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gevent-1.2.1-py3.5-macosx-10.12-x86_64.egg/gevent/_socket3.py", line 418, in sendall
    data_sent += self.send(data_memory[data_sent:], flags)
  File "/Users/ahmad/Projects/Side-Gigs/sa7beh-app/venv/lib/python3.5/site-packages/gevent-1.2.1-py3.5-macosx-10.12-x86_64.egg/gevent/_socket3.py", line 391, in send
    return _socket.socket.send(self._sock, data, flags)
OSError: [Errno 41] Protocol wrong type for socket

At this point, I am clueless to what is causing the problem. Nothing has changed in the list of dependencies.

EDIT: copy-paste the current command.

@jamadden
Copy link
Collaborator

I had already tried doing concurrency tests with ab and didn't reproduce a problem with the simple app. I installed the latest wrk from github and tried with wrk -c 1000 -t 100 -d 60 http://localhost:8000/ and still did not produce a problem...the worst I saw were a small number (~4000 out of 334,977) 'Connection reset by peer' messages when I turned logging to the DEBUG level. (Note that I'm benchmarking from the same machine gunicorn is running on.)

Can you produce a problem using the simple app? If so, that tells us its system dependent somehow. If not, that tells us its related to the code in the app you're running in some way and we'd need to simplify that to pin down the issue (in particular, I would be concerned about C extensions or CFFI code).

@jamadden
Copy link
Collaborator

I wonder if you're seeing this behaviour, which basically comes down to timing/race-type conditions. The difference in our test machines, and possibly in the amount of data being sent, might explain the reproduction issues, as well as explaining why different versions of Python and gunicorn behave differently.

@aalhour
Copy link
Author

aalhour commented Mar 21, 2017

Hello @jamadden,

I didn't test the simple app yet on my Mac machine, but I have tested it on my Linux (Lenovo) machine with Ubuntu 14.04. The error didn't show up at all. Here are the test results:

Operating System:

Linux 4.4.0-66-generic #87~14.04.1-Ubuntu

Application:

#!/usr/bin/env python3

# app.py
def app(environ, start_response):
	start_response("200 OK", [('Content-Type', 'text/plain')])
	return [b"This is some text to stream"]

Gunicorn Command:

gunicorn -k gevent -w 17 ignored_dir.app:app > test_app/log_file.log 2>&1

Python 3.5.3 + Gunicorn 19.6.0:

$ wrk -c 1000 -t 100 -d 300 http://localhost:8000
Running 5m test @ http://localhost:8000
  100 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     5.25ms   39.36ms   2.00s    99.76%
    Req/Sec   267.64    105.38     1.92k    84.58%
  1346831 requests in 5.00m, 253.06MB read
  Socket errors: connect 79, read 7515, write 0, timeout 3840
Requests/sec:   4487.95
Transfer/sec:    863.48KB

The log file contained no errors and no critical messages.

Python 3.5.3 + Gunicorn 19.7.0:

$ wrk -c 1000 -t 100 -d 300 http://localhost:8000
Running 5m test @ http://localhost:8000
  100 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.55ms   37.41ms   2.00s    99.80%
    Req/Sec   309.43    113.06     1.58k    82.08%
  1547860 requests in 5.00m, 290.82MB read
  Socket errors: connect 79, read 7529, write 0, timeout 2886
Requests/sec:   5157.81
Transfer/sec:      0.97MB

The log file contained no errors and no critical messages.

Python 3.6.0 + Gunicorn 19.7.0:

$ wrk -c 1000 -t 100 -d 300 http://localhost:8000
Running 5m test @ http://localhost:8000
  100 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.50ms   36.14ms   2.00s    99.78%
    Req/Sec   313.10    110.12     1.64k    84.30%
  1549552 requests in 5.00m, 291.14MB read
  Socket errors: connect 79, read 7617, write 0, timeout 2689
Requests/sec:   5163.45
Transfer/sec:      0.97MB

The log file contained no errors and no critical messages.

Python 3.6.0 + Gunicorn 19.7.1:

$ wrk -c 1000 -t 100 -d 300 http://localhost:8000
Running 5m test @ http://localhost:8000
  100 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.66ms   37.98ms   2.00s    99.75%
    Req/Sec   310.20    114.44     2.91k    83.92%
  1549884 requests in 5.00m, 291.21MB read
  Socket errors: connect 79, read 7428, write 0, timeout 3086
Requests/sec:   5164.55
Transfer/sec:      0.97MB

The log file contained no errors and no critical messages.

After all the tests above have resulted in good news, I went ahead and tested my own Flask application on the same machine with Python 3.6.0 and Gunicorn 19.7.1 and the error didn't appear, not even once! I tested the app twice, once with a standard Gunicorn command, and then with my own Gunicorn configuration, here are the commands:

Gunicorn Commands:

  • $ gunicorn -k gevent -w 17 sa7beh.app:app > logs/sa7beh_app.log 2>&1
  • $ gunicorn -c config/gunicorn.conf.py sa7beh.app:app > logs/sa7beh_app.log 2>&1

Wrk command:

Same command was used twice, sample result:

$ wrk -c 1000 -t 180 -d 300 http://127.0.0.1:8000/api/v1.0/users
Running 5m test @ http://127.0.0.1:8000/api/v1.0/users
  180 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    67.27ms   55.75ms   1.99s    98.86%
    Req/Sec    15.88      6.69    70.00     92.42%
  65618 requests in 5.00m, 280.06MB read
  Socket errors: connect 59, read 6747, write 0, timeout 910
  Non-2xx or 3xx responses: 10
Requests/sec:    218.65
Transfer/sec:      0.93MB

So apparently the issue, at least so far, only happens on macOS Sierra 10.12.1. I will re-run the same tests this evening on my Mac machine and copy-paste the tests results here as well.

@jamadden
Copy link
Collaborator

I didn't test the simple app yet on my Mac machine, but I have tested it on my Linux (Lenovo) machine with Ubuntu 14.04. The error didn't show up at all.

That makes sense to me, based on the research I've done. It appears to be mac-specific, quite probably even mac version specific and possibly machine specific too.

@aalhour
Copy link
Author

aalhour commented Mar 21, 2017

Hello @jamadden,

I have tested the simple app on my Mac machine once with standard configuration and a second time with my app's Gunicorn configuration and the error appeared. I have used the following wrk parameters. Python is v3.6.0 and Gunicorn is v19.7.1.

$ gunicorn -k gevent -w 17 test_app.app:app -b 127.0.0.1:5000 > test_app/test_log.log 2>&1
$ gunicorn -c config/gunicorn.conf.py test_app.app:app > test_app/test_log.log 2>&1
$ wrk -c 3600 -t 2000 -d 300 http://localhost:5000/
Running 5m test @ http://localhost:5000/
  2000 threads and 3600 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.39ms   45.25ms   2.00s    99.25%
    Req/Sec   388.73    510.11     2.32k    83.34%
  3544280 requests in 5.00m, 665.88MB read
  Socket errors: connect 0, read 8316, write 0, timeout 27177
Requests/sec:  11805.67
Transfer/sec:      2.22MB

I also tested my app with Python 3.6.0 + Gunicorn 19.7.1 and the error appeared. The weird thing though is that I tested the index page of my app which only returns an HTML static page, no database or 3rd services being accessed whatsoever, and to be 100% precise, the index page checks a cookie header and redirects to another static page for user login, but still no additional database or network access.

$ gunicorn -k gevent -w 17 -b 127.0.0.1:5000 sa7beh.app:app > logs/sa7beh_app.log 2>&1
$ gunicorn -c config/gunicorn.conf.py sa7beh.app:app > logs/sa7beh_app.log 2>&1
$ wrk -c 3600 -t 2000 -d 300 http://localhost:5000/
Running 5m test @ http://localhost:5000/
  2000 threads and 3600 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     6.64ms   24.45ms   1.98s    96.48%
    Req/Sec   127.47     70.67   404.00     68.86%
  780786 requests in 5.01m, 463.90MB read
  Socket errors: connect 0, read 22699, write 0, timeout 9594
Requests/sec:   2599.90
Transfer/sec:      1.54MB

The same error (OSError: [Errno 41] Protocol wrong type for socket) occurred 5 times:

$ grep "Protocol wrong type for socket" logs/sa7beh_app.log |wc -l
5

I tried testing one of my API endpoints on Python 3.6.0 + Gunicorn 19.7.1 and wrk and the same error appeared.

It looks like a Mac issue to me. What do you guys think?

CC @benoitc.

P.S. here is my Gunicorn config file in case you guys would like to know about all the details:

import multiprocessing as mp

bind = "127.0.0.1:5000"
worker_class = "gevent"
workers = (mp.cpu_count() * 2) + 1
daemon = False
preload_app = False
pidfile = PID_FILE_PATH
proc_name = "sa7beh_web_server"
backlog = 2048
worker_connections = 1024
max_requests = 2048
max_requests_jitter = 100
timeout = 30
keepalive = 2
logger_class = "gunicorn.glogging.Logger"
loglevel = "info"
accesslog = "-"
errorlog = "-"
log_file = LOG_FILE_PATH
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" "response_time=%(L)s seconds"'

@racitup
Copy link

racitup commented Oct 2, 2017

I'm also getting OSError: [Errno 41] Protocol wrong type for socket on my mac 10.11.6 with both gunicorn and waitress.
With gunicorn I got this:

[2017-10-02 04:01:45 +0100] [19891] [ERROR] Socket error processing request.
Traceback (most recent call last):
File "/Users/rich/.pyenv/versions/3.5.2/lib/python3.5/site-packages/gunicorn/workers/sync.py", line 135, in handle
self.handle_request(listener, req, client, addr)
File "/Users/rich/.pyenv/versions/3.5.2/lib/python3.5/site-packages/gunicorn/workers/sync.py", line 191, in handle_request
six.reraise(*sys.exc_info())
File "/Users/rich/.pyenv/versions/3.5.2/lib/python3.5/site-packages/gunicorn/six.py", line 625, in reraise
raise value
File "/Users/rich/.pyenv/versions/3.5.2/lib/python3.5/site-packages/gunicorn/workers/sync.py", line 182, in handle_request
resp.write(item)
File "/Users/rich/.pyenv/versions/3.5.2/lib/python3.5/site-packages/gunicorn/http/wsgi.py", line 362, in write
util.write(self.sock, arg, self.chunked)
File "/Users/rich/.pyenv/versions/3.5.2/lib/python3.5/site-packages/gunicorn/util.py", line 302, in write
sock.sendall(data)
OSError: [Errno 41] Protocol wrong type for socket

@tilgovi
Copy link
Collaborator

tilgovi commented Oct 2, 2017

Alright, seems like everyone experiences this as a mac error. If anyone gives me a repro repo I can try it on 10.13.

I'm not sure there's any action to take for Gunicorn.

@racitup
Copy link

racitup commented Oct 2, 2017

Seems to be an unhandled error returned by the OSX kernel.

Taken from here:

To prevent anyone else from tripping over this edge case, I filed a Apple Radar ticket (number #19012087 for any Apple employees reading this). Hopefully if anyone runs into this mysterious EPROTOTYPE it’ll be documented for them, or at least there’s a chance they’ll stumble over this blog post and save themselves a weekend diving through the OS.

It seems this error is returned by OSX in a call to sendto. He fixed it by catching the error:

} else if (errno == EPROTOTYPE) {
        continue;

Presumably this needs to be fixed in a low-level python library?

@tilgovi
Copy link
Collaborator

tilgovi commented Oct 2, 2017

errno.EPROTOTYPE is defined in Python, too. I'd say we can catch this in Gunicorn but I don't know what the right behavior for it would be.

@tilgovi
Copy link
Collaborator

tilgovi commented Dec 9, 2017

Any suggestions for what to do here?

@lucasjinreal
Copy link

macOS still got this error sometime, which is really weired. macOS version 10.13.3

@agourdin
Copy link

agourdin commented May 8, 2018

Also seeing this pop up for me on macOS version 10.12.6

@racitup
Copy link

racitup commented May 9, 2018

Since I couldn't find it on the python bugtracker, I filed it here
We'd probably be waiting forever for Apple to fix it...

@tilgovi It's been a long time since I looked at it, but since it seems to be intermittent and probably some kind of race condition, catch the exception as low as possible in gunicorn and try again, possibly adding a small delay? You could even make the code mac-specific and comment it as a workaround until python/Apple fix it? Alternatively, since the application will probably retry anyway, do nothing and mark as "known issue"?

@enugentdt
Copy link

I know it's been a while, but I'm going to hop on the bandwagon.

I run Siege to test my servers, using aiohttp, and sometimes it's behind guincorn. It appears to only happen (in my case) when I ctrl+C Siege. So I'd personally agree with the race condition idea? Or maybe it's to do with closed sockets?

But if anybody needs to test ideas, I'm more than happy to get in contact with whomever to help repro bugs. But, with my software, I can consistently produce this.

I'm running OSX 10.12.6, mid-2015 15" MBP.

Sorry if I'm late to the party or compounding something already known, or if I'm even being useless. Let me know if there's anything I can do to help.

@jaydeeponly
Copy link

The moment I stopped socketIO, the error is gone :-) I believe the problem is related with socketIO.

@OrchidHu
Copy link

[ERROR] Socket error processing request

@brian-farrell
Copy link

brian-farrell commented May 13, 2020

FYI - I came here while searching about this same error that I am seeing with with version 3.0.6 of the Django Development server on MacOS, so this error does not seem specific to gunicorn.

Here is the stack trace I'm seeing:

System check identified no issues (0 silenced).
May 13, 2020 - 15:47:15
Django version 3.0.6, using settings 'beam.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[13/May/2020 15:48:05] "GET /polls/1/ HTTP/1.1" 200 705
Not Found: /favicon.ico
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/wsgiref/handlers.py", line 138, in run
    self.finish_response()
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/wsgiref/handlers.py", line 184, in finish_response
    self.write(data)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/wsgiref/handlers.py", line 287, in write
    self.send_headers()
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/wsgiref/handlers.py", line 345, in send_headers
    self.send_preamble()
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/wsgiref/handlers.py", line 271, in send_preamble
    self._write(('Server: %s\r\n' % self.server_software).encode('iso-8859-1'))
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/wsgiref/handlers.py", line 466, in _write
    result = self.stdout.write(data)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py", line 799, in write
    self._sock.sendall(b)
OSError: [Errno 41] Protocol wrong type for socket

Just realized that I should have noted my MacOS Version: 10.14.6 (18G4032)

@guareber
Copy link

I can +1 brian-farrell's post - older django and python versions, but pretty identical stacktrace. OSX version 10.15.2 (19C57).

@arickuter
Copy link

I am still seeing this error. Has there been any resolution yet?

@ktsitsi
Copy link

ktsitsi commented Jan 22, 2021

I am seeing this error on OSX version 10.14. In my use case the error relates to GCS emulator. I can confirm that in Linux the error does not occur in the same scenario. Is there any update or fix on that? gunicorn version is the required by GCS 20.0.4

Traceback (most recent call last):
  File "/Users/runner/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/gunicorn/workers/gthread.py", line 271, in handle
    keepalive = self.handle_request(req, conn)
  File "/Users/runner/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/gunicorn/workers/gthread.py", line 340, in handle_request
    util.reraise(*sys.exc_info())
  File "/Users/runner/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/gunicorn/util.py", line 625, in reraise
    raise value
  File "/Users/runner/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/gunicorn/workers/gthread.py", line 328, in handle_request
    resp.close()
  File "/Users/runner/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/gunicorn/http/wsgi.py", line 404, in close
    util.write_chunk(self.sock, b"")
  File "/Users/runner/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/gunicorn/util.py", line 280, in write_chunk
    sock.sendall(chunk)
OSError: [Errno 41] Protocol wrong type for socket

@tilgovi
Copy link
Collaborator

tilgovi commented Feb 16, 2021

I'm not sure there's anything we can do here. We have this discussion for anyone who searches for the issue, but it seems to be an issue with macOS. I'm going to close this, but if anyone has suggestions for some action we should take, please open an issue or a PR to address this.

@tilgovi tilgovi closed this as completed Feb 16, 2021
pepoluan referenced this issue in aio-libs/aiosmtpd Feb 22, 2021
* Rename internal "args" variable in parseargs
* Add SSL parameters and combination validation
* Add certfile & keyfile validation (check they exist)
* Invert "--requiretls" to "--no-requiretls"
* Assert default values
* Implement SSL Context injection for STARTTLS and SMTPS
* Implement test for "TLS Required"
* Update CLI docs
* Properly generate man page
* Version Up + NEWS
* Run Bandit as part of testing
* Silence Bandit complaints
* Update README.rst
* Build manpage as well in GA (detect errors)
* Tidying up
* Reduce housekeep.py superclean clutter
pepoluan added a commit to pepoluan/aiosmtpd that referenced this issue Feb 23, 2021
pepoluan added a commit to aio-libs/aiosmtpd that referenced this issue Feb 24, 2021
## Change shared ctypes to MP.Queue

PyPy has problems with shared ctypes Value, especially on Windows. Not
sure why. This resulted in flakey pypy3-* tests.

Converting to MP.Queue might be slightly slower, but it's much more
stable/deterministic. And since this change impacts only 3 tests out of
several hundreds, it's worth it for the expansion of Windows test scope.

## Activate pypy3 testing in tox.ini

## Specify non-"win32" platforms for "static"

This enables us to add "static" into tox/envlist, for easier invocation.

## Change "_dynamic" to "_dump"

## Make ENV dump ".py"

So we can leverage syntax-highlighting when checking

## Also delete temporary "parallel" coverage files

## Move coverage/diffcov files

Temporary/intermediate files go to _dump

Reports go to htmlcov

## Exclude _dump from pytype

## Prefix ENV dump file with "ENV = \"

To reduce IDE protests

## Extend watched process delay by 50%

Exact same with AUTOSTOP_DELAY makes the test flakey.

## Up version to 1.4.0a4 and NEWS.rst

## Replace ConnectionError with OSError (for MacOS)

Refs:
- racitup/static-ranges#1
- benoitc/gunicorn#1487
- http://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/

## Update README.rst

- Now pypy3 is no longer a stepchild.
- Notes on which testenvs work/don't work on Cygwin.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests