Casual-Cluster with Signed certs - cluster driver not fully operational

I have a core-only cluster with 3 neo4j servers that are part of a sub-domain.

Core1 - Has 2 Network Interfaces - Public IP is the listener address
Core2 - Has 2 Network Interfaces - Public IP is the listener address
Core3 - Has 2 Network Interfaces - Public IP is the listener address


  1. <subdomain> has three A Records that point to Core1, Core2, Core3 's IP Addresses listed and this is the same used for RAFT as well. I see a lot of success information in logs as well as query info in query.log
  2. I do not use DNS names inside the neo4j.conf and instead the public IPs.


  1. It's a grandstack app. apollo-graphql and react talk to each other, Graphql talks to a SINGLE database.
  2. The core-only cluster will replace the SINGLE database when ready.

I have used Letsencrypt certbot to generate my certs i.e. publicly signed for all my cores by their IP Addresses. Each server has it's own certbot generated cert (DNS ACME Challenge).

The Cluster seems to be working. I ran a portion of my seeding and everything on the cluster looks peachy (well almost). This is not a production cluster today but in a week I want to use this as my main neo4j instances in a specific region.


  • I started having difficulties with neo4j+s driver on both GraphQL as well as on Neo4J Desktop.
  • I cannot connect directly to my cluster unless the 2. in Temporary Steps is done.


  1. I have a trust: 'TRUST_ALL_CERTIFICATES', for my GraphQL driver.
  2. I connect to botl+s://<subdomain> on neo4j desktop.
  • After connecting I do :server disconnect and then can use neo4j+s://<subdomain>

I want to fix my cluster and and my graphql as well. I cannot use the TRUST_ALL_CERTIFICATES as this is completely counter-intuitive to having publicly-signed certs.

How do I debug? How do I proceed forward? This is probably my last step before I can finalise my cluster and move to production.


Adding more useful info. I see this in the logs when I attempt to use neo4j+s from neo4j desktop.

io.netty.handler.codec.DecoderException: Received fatal alert: certificate_unknown at io.netty.handler.codec.ByteToMessageDecoder.callDecode( ~[netty-all-4.1.55.Final.jar:4.1.55.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead( ~[netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at org.neo4j.bolt.transport.pipeline.AuthenticationTimeoutTracker.channelRead( [neo4j-bolt-4.2.3.jar:4.2.3] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at$HeadContext.channelRead( [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at$EpollStreamUnsafe.epollInReady( [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$ [netty-all-4.1.55.Final.jar:4.1.55.Final] at io.netty.util.internal.ThreadExecutorMap$ [netty-all-4.1.55.Final.jar:4.1.55.Final] at [netty-all-4.1.55.Final.jar:4.1.55.Final] at [?:?] Caused by: Received fatal alert: certificate_unknown at ~[?:?] at ~[?:?] at ~[?:?] at$AlertConsumer.consume( ~[?:?] at ~[?:?] at ~[?:?] at ~[?:?] at ~[?:?] at ~[?:?] at ~[?:?] at ~[?:?] at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap( ~[netty-all-4.1.55.Final.jar:4.1.55.Final] at io.netty.handler.ssl.SslHandler.unwrap( ~[netty-all-4.1.55.Final.jar:4.1.55.Final] at io.netty.handler.ssl.SslHandler.decodeJdkCompatible( ~[netty-all-4.1.55.Final.jar:4.1.55.Final] at io.netty.handler.ssl.SslHandler.decode( ~[netty-all-4.1.55.Final.jar:4.1.55.Final] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection( ~[netty-all-4.1.55.Final.jar:4.1.55.Final]

I found my answer by reading this article on medium written by David Allen.

While the post was greatly insightful, I had to fix my bolt advertised addresses


CALL dbms.cluster.routing.getRoutingTable({}) 
YIELD ttl, servers 
UNWIND servers as server
RETURN ttl, server.role, server.addresses;


Ensure that  `dbms.connector.bolt.advertised_addres=<DNS_FOR_CLUSTER>`

In my case, the DNS A records have three IP Addresses - each my CORE CLUSTER. Phew! It was a simple thing, Glad I could figure it out myself.