Summary
When advanced.protocol.version is not set (the default), the driver negotiates the CQL protocol
version on its first connection by walking a version ladder that starts with the DataStax
Enterprise versions: DSE_V2 → DSE_V1 → V5 → V4. ScyllaDB never speaks the DSE protocol versions,
so on every driver startup the first attempts are rejected by the server and the driver downgrades
until it reaches a version ScyllaDB supports.
Observed behavior
Driver debug logs while a fresh CqlSession connects to ScyllaDB:
ChannelFactory - Failed to connect with protocol DSE_V2, retrying with DSE_V1
ChannelFactory - Failed to connect with protocol DSE_V1, retrying with V5
ChannelFactory - Failed to connect with protocol V5, retrying with V4
Server side, one rejection per attempt (captured against Simulacron, which mirrors the CQL framing):
Received message with unsupported protocol version 66 (DSE_V2), sending back protocol error
Received message with unsupported protocol version 65 (DSE_V1), sending back protocol error
Received message with unsupported protocol version 5 (V5), sending back protocol error
Each rejected attempt is a separate short-lived TCP connection that completes no handshake; the
driver then establishes its real (control) connection at the first supported version.
Why it happens
ChannelFactory leaves protocolVersion unset when the configuration doesn't pin it, and negotiates
on the first connection using the inherited DataStax ProtocolVersionRegistry, whose highest-to-lowest
ordering places the DSE versions above the OSS ones. The negotiated version is then cached
(ChannelFactory.protocolVersion), so this walk happens once per driver instance at startup, not
per connection.
Impact
- Extra startup latency: 2–3 rejected round-trips before the first usable connection.
- 2–3 throwaway TCP connections per driver initialization.
- Server-side "unsupported protocol version" rejections on every client startup — potential noise in
ScyllaDB logs/metrics.
Minor and one-time-per-process, but avoidable — and slightly surprising for a ScyllaDB-focused driver
to probe DSE protocol versions it can never use.
Suggested remediation (for discussion)
- Give this fork a sensible default for
advanced.protocol.version (e.g. the highest OSS version
ScyllaDB supports), or
- Adjust the negotiation ladder /
ProtocolVersionRegistry used by the fork so negotiation does not
start from the DSE versions.
Either removes the wasted DSE probes while preserving negotiation among the OSS versions.
Notes
Summary
When
advanced.protocol.versionis not set (the default), the driver negotiates the CQL protocolversion on its first connection by walking a version ladder that starts with the DataStax
Enterprise versions:
DSE_V2 → DSE_V1 → V5 → V4. ScyllaDB never speaks the DSE protocol versions,so on every driver startup the first attempts are rejected by the server and the driver downgrades
until it reaches a version ScyllaDB supports.
Observed behavior
Driver debug logs while a fresh
CqlSessionconnects to ScyllaDB:Server side, one rejection per attempt (captured against Simulacron, which mirrors the CQL framing):
Each rejected attempt is a separate short-lived TCP connection that completes no handshake; the
driver then establishes its real (control) connection at the first supported version.
Why it happens
ChannelFactoryleavesprotocolVersionunset when the configuration doesn't pin it, and negotiateson the first connection using the inherited DataStax
ProtocolVersionRegistry, whose highest-to-lowestordering places the DSE versions above the OSS ones. The negotiated version is then cached
(
ChannelFactory.protocolVersion), so this walk happens once per driver instance at startup, notper connection.
Impact
ScyllaDB logs/metrics.
Minor and one-time-per-process, but avoidable — and slightly surprising for a ScyllaDB-focused driver
to probe DSE protocol versions it can never use.
Suggested remediation (for discussion)
advanced.protocol.version(e.g. the highest OSS versionScyllaDB supports), or
ProtocolVersionRegistryused by the fork so negotiation does notstart from the DSE versions.
Either removes the wasted DSE probes while preserving negotiation among the OSS versions.
Notes
CqlSession(not specific to any feature); discovered while investigatingSTARTUP-frame behavior for Client config reporting — stage 1 (groundwork): SESSION_ID + DRIVER_CONFIG plumbing #967 (client configuration reporting).advanced.protocol.version = V4(orV5), which eliminates the negotiationentirely.