shadow1ng/fscan · error
cassandra error: %s
Error message
cassandra error: %s
What it means
During the Cassandra native-protocol handshake, the server replied with an ERROR frame (opcode cqlOpError) in response to the OPTIONS/STARTUP exchange. The raw server error message is wrapped as 'cassandra error: %s' and returned as an auth failure (ErrorTypeAuth).
Source
Thrown at plugins/services/cassandra.go:120
// Step 1: STARTUP (CQL_VERSION=3.0.0)
startupBody := cqlStringMap(map[string]string{"CQL_VERSION": "3.0.0"})
if err := cqlSend(conn, cqlOpStartup, startupBody); err != nil {
state.IncrementTCPFailedPacketCount()
return &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}
}
// Step 2: 读取响应
opcode, body, err := cqlRecv(conn)
if err != nil {
state.IncrementTCPFailedPacketCount()
return &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}
}
// READY → 已就绪,发送测试查询
// AUTHENTICATE → 需要认证
// ERROR → 错误
if opcode == cqlOpError {
return &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: fmt.Errorf("cassandra error: %s", string(body))}
}
// Step 3: 如果需要认证
if opcode == cqlOpAuthChl {
if cred.Username == "" && cred.Password == "" {
return &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: fmt.Errorf("authentication required")}
}
// SASL PLAIN: \x00username\x00password
saslToken := []byte("\x00" + cred.Username + "\x00" + cred.Password)
if err := cqlSend(conn, cqlOpAuthRsp, saslToken); err != nil {
state.IncrementTCPFailedPacketCount()
return &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}
}
opcode, body, err = cqlRecv(conn)
if err != nil {
state.IncrementTCPFailedPacketCount()
return &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}
}View on GitHub (pinned to 95cc12e753)
Solutions
- Read the embedded server message from the error to identify the server-side cause (e.g. unsupported protocol version).
- Adjust the CQL protocol version used by the plugin to one supported by the target Cassandra release.
- Retry later or against another node if the server reports overload/unavailable.
Defensive patterns
Strategy: try-catch
Try / catch
res := doCassandraAuth(conn, cred, state)
if !res.Success && res.ErrorType == ErrorTypeAuth {
var srvMsg string
fmt.Sscanf(res.Error.Error(), "cassandra error: %s", &srvMsg)
log.Printf("server rejected handshake: %s", srvMsg)
} Prevention
- Use a CQL protocol version supported by the target server version.
- Check server logs alongside client errors to correlate server-side rejections.
- Avoid scanning nodes that are bootstrapping or decommissioned.
When it happens
Trigger: doCassandraAuth sends the protocol STARTUP/OPTIONS frame and reads the reply; if the response opcode is cqlOpError, the server-side error body is surfaced via this error.
Common situations: Protocol version unsupported by the server; server rejecting the STARTUP options; node overloaded or bootstrapping; connecting to something that speaks CQL binary protocol but refuses the handshake.
Related errors
- unexpected opcode: %d
- cassandra frame too large: %d
- unexpected query opcode: %d
- cassandra query failed: %s
- invalid saslStart response
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/518050a34dabba91.
Report an issue: GitHub.