redis/redis-py · critical · OSError

socket.getaddrinfo returned an empty list

Error message

socket.getaddrinfo returned an empty list

What it means

Raised in _connect (connection.py:1634) when socket.getaddrinfo(self.host, self.port, ...) returns an empty list — the DNS resolver produced no usable address records for the host. This is distinct from getaddrinfo raising an exception; it means resolution 'succeeded' with zero candidates, so no socket could be created and OSError is raised.

Solutions

  1. Resolve the host yourself: python -c "import socket; print(socket.getaddrinfo('host', 6379))" to confirm DNS.
  2. Use an IP address directly to bypass DNS and isolate the problem.
  3. Fix DNS (correct name, reachable resolver, propagated record).
  4. For cluster/sentinel, ensure all node hostnames resolve from the client.
  5. Check socket_type isn't filtering out available families (e.g. forcing AF_INET on an IPv6-only host).

Example fix

# before
r = redis.Redis(host='redis-svc.myco', port=6379)  # NXDOMAIN-ish
# after
r = redis.Redis(host='10.0.0.5', port=6379)  # verified IP
Defensive patterns

Strategy: validation

Validate before calling

import socket
def resolvable(host, port=6379):
    try:
        return bool(socket.getaddrinfo(host, port, socket.SOCK_STREAM))
    except socket.gaierror:
        return False

assert resolvable(h, p), f'no DNS records for {h}'
r = redis.Redis(host=h, port=p)

Type guard

import socket
def is_resolvable(host: str, port: int = 6379) -> bool:
    try:
        return len(socket.getaddrinfo(host, port, socket.SOCK_STREAM)) > 0
    except socket.gaierror:
        return False

Try / catch

import socket
try:
    r = redis.Redis(host=h, port=p); r.ping()
except OSError as e:
    if 'getaddrinfo' in str(e):
        # fall back to a known IP or retry after DNS propagates
        r = redis.Redis(host=ip_fallback, port=p)
    else:
        raise

Prevention

When it happens

Trigger: Connecting to a hostname that resolves to nothing (no A/AAAA records), a DNS server returning an empty answer, an SRV/CNAME with no target, or a malformed host string that getaddrinfo accepts but yields no SOCK_STREAM addresses.

Common situations: Typo in hostname; DNS not yet propagated for a new service; private DNS zone unreachable from the client host; service decommissioned; ephemeral hostname from a failed deploy; IPv6-only host with IPv4-only socket_type.

Understand the failure class

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/a83c310621fe1cec. Report an issue: GitHub.

Appendix: source

Thrown at redis/connection.py:1634

                return sock

            except OSError as _:
                err = _
                if sock is not None:
                    try:
                        sock.shutdown(socket.SHUT_RDWR)  # ensure a clean close
                    except OSError:
                        pass
                    sock.close()

        if err is not None:
            try:
                raise err
            finally:
                # Ensure we clear local references to caught exceptions
                err = None
        raise OSError("socket.getaddrinfo returned an empty list")

    def _host_error(self):
        return f"{self.host}:{self.port}"

    @property
    def host(self) -> str:
        return self._host

    @host.setter
    def host(self, value: str):
        self._host = value


class CacheProxyConnection(MaintNotificationsAbstractConnection, ConnectionInterface):
    DUMMY_CACHE_VALUE = b"foo"
    MIN_ALLOWED_VERSION = "7.4.0"
    DEFAULT_SERVER_NAME = "redis"

View on GitHub (pinned to 6a6b581b48)