RedisCache - UnixDomainSocketConnection object has not attribute '_command_packer'

I’m trying to configure my production Django website to use Redis and django.core.cache.backends.redis.RedisCache, and after wrestling with permissions, I at least got the website to work momentarily. Then I started getting this exception:

'UnixDomainSocketConnection' object has no attribute '_command_packer'

Traceback (most recent call last):
  File "[...]lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "[...]lib/python3.10/site-packages/django/utils/deprecation.py", line 135, in __call__
    response = self.process_request(request)
  File "[...]lib/python3.10/site-packages/django/middleware/cache.py", line 158, in process_request
    cache_key = get_cache_key(request, self.key_prefix, "GET", cache=self.cache)
  File "[...]lib/python3.10/site-packages/django/utils/cache.py", line 390, in get_cache_key
    headerlist = cache.get(cache_key)
  File "[...]lib/python3.10/site-packages/django/core/cache/backends/redis.py", line 187, in get
    return self._cache.get(key, default)
  File "[...]lib/python3.10/site-packages/django/core/cache/backends/redis.py", line 99, in get
    value = client.get(key)
  File "[...]lib/python3.10/site-packages/redis/commands/core.py", line 1790, in get
    return self.execute_command("GET", name)
  File "[...]lib/python3.10/site-packages/redis/client.py", line 1258, in execute_command
    return conn.retry.call_with_retry(
  File "[...]lib/python3.10/site-packages/redis/retry.py", line 46, in call_with_retry
    return do()
  File "[...]lib/python3.10/site-packages/redis/client.py", line 1259, in <lambda>
    lambda: self._send_command_parse_response(
  File "[...]lib/python3.10/site-packages/redis/client.py", line 1234, in _send_command_parse_response
    conn.send_command(*args)
  File "[...]lib/python3.10/site-packages/redis/connection.py", line 916, in send_command
    self._command_packer.pack(*args),

Obviously, I’m connecting to Redis through a Unix Domain Socket. I tried a Google search for this error, and the mighty Google search gave zero (0) results. I have no idea what’s going on. I appreciate any assistance.

Have you tried using it with an IP address to try and determine whether it’s something in the socket configuration causing a problem?
(Frequently, I find that problems with unix domain sockets involve permissions. It might be worth checking out the socket to ensure your Django process has read/write access to that socket file.)

No, I haven’t. I want to avoid doing anything TCP related to keep the connection as secure as possible.

I am to connect to the Unix socket through redis-cli without any problems.

I did have a problem with permissions earlier that I think I took care of. The original configuration file set the unixsocketperm to 700. I added myuser to the redis group, and I changed unixsocketperm to 660.

# Unix socket.
#
# Specify the path for the Unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
unixsocket /var/run/redis/redis-server.sock
# unixsocketperm 700
unixsocketperm 660

How are you running your Django processes?

I’m using gunicorn and nginx. gunicorn is running Django. nginx is serving the static files and is a proxy to the gunicorn daemon.

nginx is running as www-data and gunicorn is running as myuser. Both are working just fine when I don’t have the CACHES setting installed.

What user is the gunicorn daemon running as?

Are you running it as multiprocess or multithreaded? (If you’re trying to run it as multithreaded, try running it as multiprocess.)

And I would still recommend just trying it as an IP connection to help isolate where the problem may reside.

gunicorn is running as myuser

It was a bug in redis-py, fixed today Release 4.5.1 · redis/redis-py · GitHub

2 Likes

imichaelmoore, thank you so very much! That fixed the issue! I never would have guessed. Hindsight is 20/20, though. There weren’t any Google hits, so that could mean that it was a recently introduced bug that had not been documented anywhere.