Problems connecting via python driver but can access via cypher-shell and desktop

We are having an issue connecting via the GraphDatabase.driver to a remote database running in a Kubernetes cluster. We can connect to the database fine using cypher-shell and the desktop/browser but we are unable to connect via the python driver. The full debug list is attached and at this point we are at our wits end. In the case below we are trying a basic non-encrypted connection, when we try with encryption we get an SSL error and the connection is terminated. It should also be noted that this process is not running in a container but on computers outside of the namespace, I would have thought a firewall issue but given we can connect using the same protocol from the desktop and cypher-shell running on the same machines we are kind of stumped at this point.

We do go through load balancers and port 443 is forwarded to 7687 on the pod.

Windows Version:
$ uname -a
MINGW64_NT-10.0-19045 LWFSKN6G3 3.5.4-395fda67.x86_64 2024-11-25 09:49 UTC x86_64 Msys

$ pip freeze | grep neo4j
neo4j==5.28.1
Python 3.12.9

neo4j version is 5.24.1 Community edition.

from neo4j import GraphDatabase, Driver, Session from neo4j.debug import watch

watch("neo4j")

URI = "neo4j://uri:443"
AUTH = ("f10ctli", "password")

with GraphDatabase.driver(URI,
auth=AUTH,
#database="neo4j",
encrypted=False,
) as driver:
print("checking driver")

print(driver.verify_connectivity())

[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,438 [#0000] _: created, routing address IPv4Address(('100.64.1.62', 443))
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,438 [#0000] _: routing towards fixed database: neo4j
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,439 [#0000] _: pinning database: 'neo4j'
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,439 [#0000] _: acquire routing connection, access_mode='READ', database=AcquisitionD
atabase(name='neo4j', guessed=False)
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,439 [#0000] _: attempting to update routing table from IPv4Address(('100.64.1.62', 4
43))
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,440 [#0000] _: in: 100.64.1.62:443
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,442 [#0000] _: dns resolver out: 100.64.1.62:443
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,442 [#0000] _: _acquire router connection, database='neo4j', address=ResolvedIPv4Add
ress(('100.64.1.62', 443))
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,443 [#0000] _: trying to hand out new connection
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,443 [#0000] C: 100.64.1.62:443
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,445 [#F425] C: 0x6060B017
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,445 [#F425] C: 0x000001FF 0x00080805 0x00020404 0x00000003
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,656 [#F425] S: 100.64.1.62:443 ServiceUnavailable: Failed to read four
byte Bolt handshake response from server ResolvedIPv4Address(('100.64.1.62', 443)) (deadline Deadline(timeout=60.0))
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,657 [#0000] _: deactivating address ResolvedIPv4Address(('100.64.1.62', 443))
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,657 [#0000] _: table={}
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,658 [#0000] _: failed to fetch routing info from ResolvedIPv4Address(('100.64.1.62',
443))
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,658 [#0000] _: deactivating address IPv4Address(('100.64.1.62', 443))
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,658 [#0000] _: table={}
[ERROR ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,658 Unable to retrieve routing information
[DEBUG ] [Thread 18344] [Task None ] 2025-02-26 14:13:48,659 [#0000] _: close
Traceback (most recent call last):
File "C:\Users\f10ctli\src\neo.py", line 16, in
print(driver.verify_connectivity())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\f10ctli\AppData\Roaming\Python\Python312\site-packages\neo4j_sync\driver.py", line 1082, in verify_connectivity
self._get_server_info(session_config)
File "C:\Users\f10ctli\AppData\Roaming\Python\Python312\site-packages\neo4j_sync\driver.py", line 1297, in _get_server_info
return session._get_server_info()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\f10ctli\AppData\Roaming\Python\Python312\site-packages\neo4j_sync\work\session.py", line 183, in _get_server_info
self._connect(READ_ACCESS, liveness_check_timeout=0)
File "C:\Users\f10ctli\AppData\Roaming\Python\Python312\site-packages\neo4j_sync\work\session.py", line 136, in _connect
super()._connect(
File "C:\Users\f10ctli\AppData\Roaming\Python\Python312\site-packages\neo4j_sync\work\workspace.py", line 199, in _connect
self._connection = self.pool.acquire(**acquire_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\f10ctli\AppData\Roaming\Python\Python312\site-packages\neo4j_sync\io_pool.py", line 1161, in acquire
self.ensure_routing_table_is_fresh(
File "C:\Users\f10ctli\AppData\Roaming\Python\Python312\site-packages\neo4j_sync\io_pool.py", line 1084, in ensure_routing_table_is_fresh
self.update_routing_table(
File "C:\Users\f10ctli\AppData\Roaming\Python\Python312\site-packages\neo4j_sync\io_pool.py", line 1011, in update_routing_table
raise ServiceUnavailable("Unable to retrieve routing information")
neo4j.exceptions.ServiceUnavailable: Unable to retrieve routing information

I have similar errors when running GraphDatabase.Driver from my custom class

class customerRelationsDatabase:

def __init__(self, uri, user, password):
    self.driver = GraphDatabase.driver(
        uri,
        auth=basic_auth(user, password),
    )

def initialise_graph(self):
    with self.driver.session() as session:
        session.run(
            """
                MATCH (n)
                DETACH DELETE n

                CREATE 
                    (sophie:Customer {name: 'Sophie'}),
                    (jeremy:Customer {name: 'Jeremy'}),
                    (clem:Customer {name: 'Clem'}),
                    (antonio:Customer {name: 'Antonio'}),
                    (rosa:Customer {name: 'Rosa'}),
                    (karl:Customer {name: 'Karl'}),
                    (nye:Customer {name: 'Nye'})

                CREATE 
                    (shureE215:Product {category: 'Audio|Wired|Earphones|Products', mfr: 'Shure', model: 'E215'}),
                    (boseQC3511:Product {category: 'Audio|Wired and Wireless|Earphones|Products', mfr: 'Bose', model: 'QC3511'}),
                    (appleEarpods:Product {category: 'Audio|Wireless|Earphones|Products', mfr: 'Apple', model: 'Earpods'})
                
                CREATE 
                    (sophie)-[:BOUGHT]->(shureE215),
                    (jeremy)-[:BOUGHT]->(shureE215),
                    (clem)-[:BOUGHT]->(boseQC3511),
                    (antonio)-[:BOUGHT]->(shureE215),
                    (rosa)-[:BOUGHT]->(shureE215),
                    (karl)-[:BOUGHT]->(shureE215),
                    (karl)-[:BOUGHT]->(appleEarpods),
                    (nye)-[:BOUGHT]->(appleEarpods)
            """
        )

def visualise_graph(self):
    with self.driver.session() as session:
        query = """
            MATCH (c:Customer)-[:BOUGHT]->(p:Product)
            RETURN c.name AS customer, p.model AS model, p.mfr AS mfr, p.category AS category
        """
        results = session.run(query)

        net = Network(height='750px', width='100%', bgcolor='#ffffff', font_color='black', directed=True)
        net.force_atlas_2based()

        added_nodes = set()
        added_edges = set()  # Track (source, target)

        for record in results:
            cust = record["customer"]
            model = record["model"]
            mfr = record["mfr"]
            category = record["category"]
            product_label = f"{mfr} {model}"

            # Add nodes
            if cust not in added_nodes:
                net.add_node(cust, label=cust, shape='ellipse', color='lightblue')
                added_nodes.add(cust)

            if product_label not in added_nodes:
                net.add_node(product_label, label=f"{product_label}\n{category}", shape='box', color='orange')
                added_nodes.add(product_label)

            # Add edge only once
            edge_key = (cust, product_label)
            if edge_key not in added_edges:
                net.add_edge(cust, product_label, label='BOUGHT')
                added_edges.add(edge_key)

    # Save and open
    path = os.path.abspath("../../Playground/output/customer_product_graph.html")
    net.write_html(path)
    webbrowser.open("file://" + os.path.abspath(path))

def close(self):
    self.driver.close()

The custom class is executed through the following code snippets:

db = customerRelationsDatabase(uri, username, password)

db.initialise_graph()

db.visualise_graph()

db.close()

Despite having a similar function working when testing a random GraphDatabase "

import time
from neo4j.exceptions import ServiceUnavailable

for attempt in range(3):
try:
driver = GraphDatabase.driver(uri, auth=(username, password))
with driver.session() as session:
print("Connection successful")
break
except ServiceUnavailable as e:
print(f"Attempt {attempt+1}: {e}")
time.sleep(5)
driver.close()

", the custom customer class function causes an error "ServiceUnavailable: Couldn't connect to 44.206.255.220:7687 (resolved to ('44.206.255.220:7687',)):" when it is initialised.

How to resolve this issue?

I have been trying to figure out what has been going on and I batched up the requests to include smaller amounts of data and it worked. This also only appears to happen when going to an Aura DB through the internet. If I run this on an internal network it works just fine.