Search code examples
spring-bootcassandraspring-datacassandra-3.0spring-data-cassandra

NoHostAvailableException: All host(s) tried for query failed


When I connected a single node cassandra it is working fine. Where as I connected a three node cluster (10.20.12.20, 10.20.12.21, 10.20.12.22) it is throwing below error. Why it is trying to connect localhost ?

Caused by: com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: localhost/0:0:0:0:0:0:0:1:9042 (com.datastax.driver.core.exceptions.TransportException: [localhost/0:0:0:0:0:0:0:1:9042] Cannot connect), localhost/127.0.0.1:9042 (com.datastax.driver.core.exceptions.TransportException: [localhost/127.0.0.1:9042] Cannot connect))
at com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:232) ~[cassandra-driver-core-3.4.0.jar:na]
at com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:79) ~[cassandra-driver-core-3.4.0.jar:na]
at com.datastax.driver.core.Cluster$Manager.negotiateProtocolVersionAndConnect(Cluster.java:1619) ~[cassandra-driver-core-3.4.0.jar:na]
at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1537) ~[cassandra-driver-core-3.4.0.jar:na]
at com.datastax.driver.core.Cluster.init(Cluster.java:159) ~[cassandra-driver-core-3.4.0.jar:na]

Solution

  • By default (in case of any error or missing property) it will try to connect to localhost, as that is set as DEFAULT_CONTACT_POINTS

    Your syntax is correct, my guess would be that the property is not read by your application at all. You can try to debug it and verify.

    As for debug: the contactpoints are set here, if you check it will always set to default=localhost.

    In your CassandraConfig beside overriding the getKeyspaceName() method, you also need to Override the cluster() and cassandraMapping() methods to make it work with your desired setup. E.g:

    @Configuration
    public class CassandraConfig extends AbstractCassandraConfiguration {
    
        public static final String KEYSPACE = "my_keyspace";
        // read contact points from config
        @Value("${spring.data.cassandra.contact-points}")
        private String contactPoints;
    
    
        @Override
        public CassandraClusterFactoryBean cluster() {
            CassandraClusterFactoryBean bean = super.cluster();
            bean.setContactPoints(contactPoints);
            return bean;
        }
    

    Also a side note: you will get the expected behaviour, if you only add one contact-point, as the driver will look-up all the available nodes. Actually in case if you want to restrict communication with a specific node, you need to implement loadBalancingPolicy for exlusion.