VivekVelvaluri avatar image
2 Votes"
VivekVelvaluri asked VivekVelvaluri commented

Unable to connect to Cosmos DB through Cassandra API(gocql)

I have provisioned a Cosmos DB (Cassandra API) instance on Azure.
I'm able to connect to it through cqlsh. But, getting different errors when trying to connect to it through gocql.

The following code generates this error:

gocql: unable to dial control conn read tcp> read: connection reset by peer

Here's the code snippet:

 cluster := gocql.NewCluster("<host here>")
 cluster.Port = 10350
 cluster.Timeout = 10000
 cluster.SocketKeepalive = 60 * time.Second
 cluster.RetryPolicy = &gocql.SimpleRetryPolicy{NumRetries: 3}
 cluster.Consistency = gocql.LocalOne
 cluster.ProtoVersion = 1
 cluster.ReconnectionPolicy = &gocql.ConstantReconnectionPolicy{MaxRetries: 10, Interval: 8 * time.Second}
 cluster.Keyspace = "<keyspace here>"
 cluster.DisableInitialHostLookup = true
 cluster.IgnorePeerAddr = true
 cluster.Authenticator = gocql.PasswordAuthenticator{Username: "<username here>", Password: "<password here>"}
 _, err := cluster.CreateSession()
 if err != nil{
 // handle the error

Just to add to this, gocql is listed as an officially supported driver under this page:

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

TheovanKraay-7359 avatar image
1 Vote"
TheovanKraay-7359 answered VivekVelvaluri commented

Hello. One aspect missing is SSL. You either need to enable client-side SSL server cert verification, or set sslOptions.EnableHostVerification to false. Also, ensure the values you are passing for the Cosmos DB Cassandra API account are correct. Here is a snippet which hopefully works better for you:

 // connect to the cluster
 cluster := gocql.NewCluster("<ACCOUNTNAME>")
 cluster.Port = 10350
 var sslOptions = new(gocql.SslOptions)

 // If you want to enable client-side SSL server cert verification do this:
 // sslOptions.EnableHostVerification = true
 // sslOptions.CaPath = "<path/to/cert.pem>"
 // sslOptions.Config = &tls.Config{}
 // sslOptions.ServerName = ``
 // cluster.SslOpts = sslOptions

 //If you do NOT want to enable client-side SSL, set sslOptions.EnableHostVerification to false and ignore the other options.
 sslOptions.EnableHostVerification = false
 cluster.SslOpts = sslOptions

 cluster.ProtoVersion = 4
 cluster.Authenticator = gocql.PasswordAuthenticator{Username: "<ACCOUNTNAME>", Password: "<PASSWORD>"}
 session, _ := cluster.CreateSession()
 defer session.Close()

 var pk int32
 var ck int32
 var col1 string
 var col2 int64

 if err := session.Query(`SELECT * FROM kspc1.tbl1;`).Scan(&pk, &ck, &col1, &col2); err != nil {
 fmt.Println("Row:", pk, ck, col1, col2)

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@TheovanKraay-7359 Thanks for the suggestions. I tried out both the approaches suggested by you (with and without SSL), but still running into the following error:

gocql: unable to dial control conn gocql: no response to connection startup within timeout

I tried increasing the timeout value as well, still no luck. I verified the credentials, they are correct, I am able to connect through CQLSH like I said.

Not sure what I'm doing wrong. Let me know if you have any other suggestions.

Thanks again.

1 Vote 1 ·

Figured out the solution thanks to this stackoverflow answer

Just needed to add these 2 lines to @TheovanKraay-7359's snippet:

 cluster.ConnectTimeout = 5 * time.Second
 cluster.DisableInitialHostLookup = true

I was instead doing: cluster.Timeout = 100000

Thanks a lot for your help @TheovanKraay-7359

1 Vote 1 ·