-
Notifications
You must be signed in to change notification settings - Fork 642
Description
Originally noted when this sample client:
package main
import (
"fmt"
gocql "github.com/apache/cassandra-gocql-driver/v2"
)
func main() {
cluster := gocql.NewCluster("127.0.0.1")
cluster.Logger = gocql.NewLogger(gocql.LogLevelDebug)
//cluster.ProtoVersion = 4
session, err := cluster.CreateSession()
if err != nil {
fmt.Println(err)
}
var dse_version string
query := session.Query(`select dse_version from system.local`).Consistency(gocql.One)
if err = query.Scan(&dse_version); err != nil {
fmt.Println(err)
}
fmt.Println("Version is: ", dse_version)
}built against v2.0.0-rc1 fails against DSE 6.9.0 with the following error:
$ ./version
2025/09/24 15:15:39 DBG gocql: Discovered protocol version using host. protocol_version=5 host_addr=127.0.0.1 host_id=
2025/09/24 15:15:39 INF gocql: Discovered protocol version. protocol_version=5
2025/09/24 15:15:39 WRN gocql: Control connection error. host_addr=127.0.0.1 host_id= err=gocql: crc24 mismatch in frame header, computed: 7052973, got: 0
2025/09/24 15:15:39 DBG gocql: Reconnecting the control connection.
2025/09/24 15:15:39 ERR gocql: Unable to connect to any ring node, control connection falling back to initial contact points. err=
2025/09/24 15:15:39 INF gocql: Control connection setup failed after connecting to host. host_addr=127.0.0.1 port=9042 host_id= err=could not retrieve control host info: gocql: crc24 mismatch in frame header, computed: 7052973, got: 0
gocql: unable to create session: unable to connect to initial hosts: could not retrieve control host info: gocql: crc24 mismatch in frame header, computed: 7052973, got: 0
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x201c94]
goroutine 1 [running]:
github.com/apache/cassandra-gocql-driver/v2.(*Query).defaultsFromSession(...)
/home/mersault/go/pkg/mod/github.com/apache/cassandra-gocql-driver/[email protected]/session.go:1021
github.com/apache/cassandra-gocql-driver/v2.(*Session).Query(0x0, {0x2f772f, 0x24}, {0x0, 0x0, 0x0})
/home/mersault/go/pkg/mod/github.com/apache/cassandra-gocql-driver/[email protected]/session.go:436 +0x94
main.main()
/home/mersault/work/scratch/gocql-dse/version.go:20 +0x1ec
What's happening here is that the driver is trying to use some session-level values as defaults for the query struct and is failing to do so because those values are nil. Those values are nil because the session setup never happens, and that fails because we're trying to apply protocol v5 frame decoding rules to a DSE server which (at best) speaks protocol DSEv2.
This begs the question though... why did the client apply v5 framing rules in this case? Clearly it did so because it detected protocol v5 was agreeable to both parties (see the log messages in the snippet above)... but that's clearly false. So what's going on here? The protocol detection logic (it's not really a negotiation as such) lives here. When v5 support was added we wound up modifying the session-level connection config to v5 as part of the detection logic (and we don't reset it if detection fails) which isn't great (since we're modifying session-level state in order to try and perform detection) but that isn't the big problem.
Much more significant is the fact that we consider a protocol workable if we're able to dial the remote host without errors using that protocol version. The thing is that "dial the remote host" here means establish a socket connection and exchange STARTUP messages (and responses). And according to the protocol v5 spec these messages are always unframed. That means we'll always be able to handle those responses for any server... and since we're starting with protocol v5 we'll always wind up returning v5 as the protocol version.
To confirm I tried the exact same code against Cassandra 3.11.9 which does not support protocol v5. The results were basically the same:
$ ./version
2025/09/24 15:31:57 DBG gocql: Discovered protocol version using host. protocol_version=5 host_addr=127.0.0.1 host_id=
2025/09/24 15:31:57 INF gocql: Discovered protocol version. protocol_version=5
2025/09/24 15:31:57 WRN gocql: Control connection error. host_addr=127.0.0.1 host_id= err=gocql: crc24 mismatch in frame header, computed: 6994124, got: 0
2025/09/24 15:31:57 DBG gocql: Reconnecting the control connection.
2025/09/24 15:31:57 ERR gocql: Unable to connect to any ring node, control connection falling back to initial contact points. err=
2025/09/24 15:31:57 INF gocql: Control connection setup failed after connecting to host. host_addr=127.0.0.1 port=9042 host_id= err=could not retrieve control host info: gocql: crc24 mismatch in frame header, computed: 6994124, got: 0
gocql: unable to create session: unable to connect to initial hosts: could not retrieve control host info: gocql: crc24 mismatch in frame header, computed: 6994124, got: 0
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x201c94]
goroutine 1 [running]:
github.com/apache/cassandra-gocql-driver/v2.(*Query).defaultsFromSession(...)
/home/mersault/go/pkg/mod/github.com/apache/cassandra-gocql-driver/[email protected]/session.go:1021
github.com/apache/cassandra-gocql-driver/v2.(*Session).Query(0x0, {0x2f772f, 0x24}, {0x0, 0x0, 0x0})
/home/mersault/go/pkg/mod/github.com/apache/cassandra-gocql-driver/[email protected]/session.go:436 +0x94
main.main()
/home/mersault/work/scratch/gocql-dse/version.go:20 +0x1ec