Problem
Since a0cde2e019, control-connection topology refresh no longer assigns system.local.listen_address to the local Host.
The attribute remains part of the public Host contract:
|
listen_address = None |
|
""" |
|
listen address configured for the node, *if available*: |
|
|
|
'system.local.listen_address' |
|
|
|
This is only available in the ``system.local`` table for newer versions of Cassandra. It is also not |
|
queried if :attr:`~.Cluster.token_metadata_enabled` is ``False``. Usually the same as ``broadcast_address`` |
|
unless configured differently in cassandra.yaml. |
|
""" |
|
|
|
listen_port = None |
|
""" |
|
listen port configured for the node, *if available*: |
|
|
|
'system.local.listen_port' |
|
|
|
This is only available in the ``system.local`` table for newer versions of Cassandra. It is also not |
|
queried if :attr:`~.Cluster.token_metadata_enabled` is ``False``. |
Current refresh copies broadcast fields but omits local listen metadata:
|
host.host_id = host_id |
|
host.broadcast_address = _NodeInfo.get_broadcast_address(row) |
|
host.broadcast_port = _NodeInfo.get_broadcast_port(row) |
|
host.broadcast_rpc_address = _NodeInfo.get_broadcast_rpc_address(row) |
|
host.broadcast_rpc_port = _NodeInfo.get_broadcast_rpc_port(row) |
|
host.release_version = row.get("release_version") |
|
host.dse_version = row.get("dse_version") |
|
host.dse_workload = row.get("workload") |
|
host.dse_workloads = row.get("workloads") |
|
|
|
if row is local_row: |
|
connection._control_connection_host_id = host_id |
|
|
|
tokens = row.get("tokens", None) |
|
if partitioner and tokens and self._token_meta_enabled: |
|
token_map[host] = tokens |
|
self._cluster.metadata.update_host(host, old_endpoint=endpoint) |
Code before the regression populated it:
|
host = self._cluster.metadata.get_host(connection.original_endpoint) |
|
if host: |
|
datacenter = local_row.get("data_center") |
|
rack = local_row.get("rack") |
|
self._update_location_info(host, datacenter, rack) |
|
|
|
# support the use case of connecting only with public address |
|
if isinstance(self._cluster.endpoint_factory, SniEndPointFactory): |
|
new_endpoint = self._cluster.endpoint_factory.create(local_row) |
|
|
|
if new_endpoint.address: |
|
host.endpoint = new_endpoint |
|
|
|
host.host_id = local_row.get("host_id") |
|
|
|
found_host_ids.add(host.host_id) |
|
found_endpoints.add(host.endpoint) |
|
|
|
host.listen_address = local_row.get("listen_address") |
|
host.listen_port = local_row.get("listen_port") |
|
host.broadcast_address = _NodeInfo.get_broadcast_address(local_row) |
|
host.broadcast_port = _NodeInfo.get_broadcast_port(local_row) |
|
|
|
host.broadcast_rpc_address = _NodeInfo.get_broadcast_rpc_address(local_row) |
|
host.broadcast_rpc_port = _NodeInfo.get_broadcast_rpc_port(local_row) |
Regression commit:
a0cde2e
Impact
When CQL RPC address changes but REST/listen address stays unchanged, Host.listen_address remains None. Consumers fall back to the relocated RPC endpoint and contact the wrong REST address.
Tested with ScyllaDB 2026.2.6 (c06236b53803b96e7d2d21b4fad144a9eef2c3ba) and python-driver PR #944 (83bdd4605468f73bfcee80588aa8f1be5f87d9ef). Driver 3.29.7 passes; PR #944 fails.
Related test from testpy
https://github.com/scylladb/scylladb/blob/c06236b53803b96e7d2d21b4fad144a9eef2c3ba/test/cluster/test_change_rpc_address.py#L40-L89
The test changes only the CQL RPC address, then obtains the REST address from Host.listen_address:
https://github.com/scylladb/scylladb/blob/c06236b53803b96e7d2d21b4fad144a9eef2c3ba/test/pylib/rest_client.py#L775-L781
Actual: Host.listen_address is None; REST request targets the relocated RPC IP and fails with ConnectionRefusedError.
Expected: local Host.listen_address matches system.local.listen_address after topology refresh.
Problem
Since
a0cde2e019, control-connection topology refresh no longer assignssystem.local.listen_addressto the localHost.The attribute remains part of the public
Hostcontract:python-driver/cassandra/pool.py
Lines 95 to 113 in 83bdd46
Current refresh copies broadcast fields but omits local listen metadata:
python-driver/cassandra/cluster.py
Lines 4209 to 4225 in 83bdd46
Code before the regression populated it:
python-driver/cassandra/cluster.py
Lines 3819 to 3843 in a3adf76
Regression commit:
a0cde2e
Impact
When CQL RPC address changes but REST/listen address stays unchanged,
Host.listen_addressremainsNone. Consumers fall back to the relocated RPC endpoint and contact the wrong REST address.Tested with ScyllaDB
2026.2.6(c06236b53803b96e7d2d21b4fad144a9eef2c3ba) and python-driver PR #944 (83bdd4605468f73bfcee80588aa8f1be5f87d9ef). Driver 3.29.7 passes; PR #944 fails.Related test from testpy
https://github.com/scylladb/scylladb/blob/c06236b53803b96e7d2d21b4fad144a9eef2c3ba/test/cluster/test_change_rpc_address.py#L40-L89
The test changes only the CQL RPC address, then obtains the REST address from
Host.listen_address:https://github.com/scylladb/scylladb/blob/c06236b53803b96e7d2d21b4fad144a9eef2c3ba/test/pylib/rest_client.py#L775-L781
Actual:
Host.listen_address is None; REST request targets the relocated RPC IP and fails withConnectionRefusedError.Expected: local
Host.listen_addressmatchessystem.local.listen_addressafter topology refresh.