I recently found that a Django system would sometimes return 400 responses. In the logs, right above the Bad Request entry, there was also this message:
The request’s session was deleted before the request completed. The user may have logged out in a concurrent request, for example.
At first that message was not very intuitive, so I searched for the exact string and found that it comes from django.contrib.sessions.middleware.SessionMiddleware:
1 | # Save the session data and refresh the client cookie. |
So the error is raised when saving the session fails.
In our case, sessions were stored with Django’s cached_db backend. Memcached is usually not the unstable part, so the more likely explanation was that the database became temporarily read-only or unavailable for writes. After checking the database restart logs, that turned out to be exactly what had happened at the time of the error.
I also remembered that we had enabled SESSION_SAVE_EVERY_REQUEST so users would not be logged out unexpectedly during active use. But that setting also means request.session.save() happens on every request, which in turn means a database write attempt on every request.
So in practice the situation seems to come down to three options:
- ignore it if it only happens during rare database restarts
- switch to a more reliable session storage strategy
- turn off
SESSION_SAVE_EVERY_REQUEST
At least in our case, the log message was more about a failed session write than anything mysterious happening inside Django itself.