uWSGI, Flask, sqlalchemy, and postgres: SSL error: decryption failed or bad record mac uWSGI, Flask, sqlalchemy, and postgres: SSL error: decryption failed or bad record mac nginx nginx

uWSGI, Flask, sqlalchemy, and postgres: SSL error: decryption failed or bad record mac


The issue ended up being uwsgi's forking.

When working with multiple processes with a master process, uwsgi initializes the application in the master process and then copies the application over to each worker process. The problem is if you open a database connection when initializing your application, you then have multiple processes sharing the same connection, which causes the error above.

The solution is to set the lazy configuration option for uwsgi, which forces a complete loading of the application in each process:

lazy

Set lazy mode (load apps in workers instead of master).

This option may have memory usage implications as Copy-on-Write semantics can not be used. When lazy is enabled, only workers will be reloaded by uWSGI’s reload signals; the master will remain alive. As such, uWSGI configuration changes are not picked up on reload by the master.

There's also a lazy-apps option:

lazy-apps

Load apps in each worker instead of the master.

This option may have memory usage implications as Copy-on-Write semantics can not be used. Unlike lazy, this only affects the way applications are loaded, not master’s behavior on reload.

This uwsgi configuration ended up working for me:

[uwsgi]socket = /tmp/my_app.socklogto = /var/log/my_app.logplugins = python3virtualenv =  /path/to/my/venvpythonpath = /path/to/my/appwsgi-file = /path/to/my/app/application.pycallable = appmax-requests = 1000chmod-socket = 666chown-socket = www-data:www-datamaster = trueprocesses = 2no-orphans = truelog-date = trueuid = www-datagid = www-data# the fixlazy = truelazy-apps = true


As an alternative you might dispose the engine. This is how I solved the problem.

Such issues may happen if there is a query during the creation of the app, that is, in the module that creates the app itself. If that states, the engine allocates a pool of connections and then uwsgi forks.

By invoking 'engine.dispose()', the connection pool itself is closed and new connections will come up as soon as someone starts making queries again. So if you do that at the end of the module where you create your app, new connections will be created after the UWSGI fork.


I am running a flask app using gunicorn on Heroku. My application started exhibiting this problem when I added the --preload option to my Procfile. When I removed that option, my application resumed functioning as normal.