redis/redis-py · error · DataError

get_node requires one of the following: 1. node name 2. host

Error message

get_node requires one of the following: 1. node name 2. host and port

What it means

A DataError raised by NodesManager.get_node() when called with neither a node_name nor a (host, port) pair. get_node() needs exactly one identifier to look up a node in the nodes_cache: either the cluster node name (node id) or a host+port tuple. With no identifier there is nothing to look up, so it rejects the call rather than returning an ambiguous result.

Source

Thrown at redis/asyncio/cluster.py:2049

            self._event_dispatcher = EventDispatcher()
        else:
            self._event_dispatcher = event_dispatcher

    def get_node(
        self,
        host: Optional[str] = None,
        port: Optional[int] = None,
        node_name: Optional[str] = None,
    ) -> Optional["ClusterNode"]:
        if host and port:
            # the user passed host and port
            if host == "localhost":
                host = socket.gethostbyname(host)
            return self.nodes_cache.get(get_node_name(host=host, port=port))
        elif node_name:
            return self.nodes_cache.get(node_name)
        else:
            raise DataError(
                "get_node requires one of the following: 1. node name 2. host and port"
            )

    def set_nodes(
        self,
        old: Dict[str, "ClusterNode"],
        new: Dict[str, "ClusterNode"],
        remove_old: bool = False,
    ) -> None:
        if remove_old:
            for name in list(old.keys()):
                if name not in new:
                    # Node is removed from cache before disconnect starts,
                    # so it won't be found in lookups during disconnect
                    # Mark active connections so in-flight commands can
                    # finish, then disconnect them when their current
                    # operation completes. Free connections can be
                    # disconnected immediately.

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Provide both host and port: rc.get_node(host='10.0.0.1', port=6379).
  2. Or provide the node name: rc.get_node(node_name='<cluster-node-id>').
  3. If you want the default node, use rc.get_default_node() instead of get_node().

Example fix

// before
node = rc.get_node(host='10.0.0.1')

// after
node = rc.get_node(host='10.0.0.1', port=6379)
Defensive patterns

Strategy: validation

Validate before calling

from typing import Optional

def lookup_node(rc, host=None, port=None, node_name=None):
    if node_name:
        return rc.get_node(node_name=node_name)
    if host and port:
        return rc.get_node(host=host, port=port)
    raise ValueError('Provide node_name, or both host and port')

Type guard

from typing import Optional

def has_node_identifier(host: Optional[str], port: Optional[int], node_name: Optional[str]) -> bool:
    return bool(node_name) or (bool(host) and bool(port))

Try / catch

from redis.exceptions import DataError

try:
    node = rc.get_node(host=h, port=p, node_name=n)
except DataError as e:
    if 'get_node requires' in str(e):
        raise ValueError('Pass either node_name or (host, port)') from e
    raise

Prevention

When it happens

Trigger: Calling rc.get_node() with no arguments; calling rc.get_node(host='1.2.3.4') without port, or rc.get_node(port=6379) without host — the branch logic at cluster.py:2041-2048 requires both host AND port for that path, or a node_name.

Common situations: Introspection helper code that calls get_node() expecting the default/current node; passing only host because the caller assumed a default port; refactoring that drops one of the two coordinate arguments.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/1b6c6baf05b6fc3d.json. Report an issue: GitHub.