redis/redis-py · error · DataError

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

Error message

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

What it means

Raised as a DataError by NodesFlagsCache.get_node() when the caller supplies neither a node_name nor a host+port pair. The lookup needs at least one of those identifiers to index into nodes_cache, so an empty call is treated as a programmer error rather than returning a misleading None.

Solutions

  1. Pass node_name= returned from an existing node's .name attribute.
  2. Pass both host= and port= together.
  3. Check parameter names exactly: host, port, node_name (not 'name' or 'hostname').
  4. If you want any default node, use cluster.get_default_node() instead.

Example fix

// before
node = cluster.get_node()

// after
node = cluster.get_node(host='localhost', port=7000)
# or
node = cluster.get_node(node_name='localhost:7000')
Defensive patterns

Strategy: validation

Validate before calling

def lookup_node(cluster, host=None, port=None, node_name=None):
    if node_name:
        return cluster.get_node(node_name=node_name)
    if host and port:
        return cluster.get_node(host=host, port=port)
    return cluster.get_default_node()  # fallback instead of raising

Type guard

null

Try / catch

from redis.exceptions import DataError
try:
    node = cluster.get_node(**kwargs)
except DataError as e:
    if 'get_node requires' in str(e):
        node = cluster.get_default_node()

Prevention

When it happens

Trigger: Calling cluster.get_node() with no arguments, or with only one of host/port (e.g. get_node(host='localhost')). The method requires either both host and port or a node_name.

Common situations: Wrapping get_node in helper code that conditionally passes kwargs and ends up passing none; typo'd keyword (host= vs hostname=, name= vs node_name=).

Related errors


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

Appendix: source

Thrown at redis/asyncio/cluster.py:2050

            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 6a6b581b48)