{"record":{"id":"9928da084103a38c","repo":"shadow1ng/fscan","slug":"unexpected-opcode-d","errorCode":null,"errorMessage":"unexpected opcode: %d","messagePattern":"unexpected opcode: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/cassandra.go","lineNumber":145,"sourceCode":"\t\t}\n\t\t// SASL PLAIN: \\x00username\\x00password\n\t\tsaslToken := []byte(\"\\x00\" + cred.Username + \"\\x00\" + cred.Password)\n\t\tif err := cqlSend(conn, cqlOpAuthRsp, saslToken); err != nil {\n\t\t\tstate.IncrementTCPFailedPacketCount()\n\t\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}\n\t\t}\n\t\topcode, body, err = cqlRecv(conn)\n\t\tif err != nil {\n\t\t\tstate.IncrementTCPFailedPacketCount()\n\t\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}\n\t\t}\n\t\t// AUTH_SUCCESS → 认证成功\n\t\t// ERROR → 认证失败\n\t\tif opcode == cqlOpError {\n\t\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: fmt.Errorf(\"authentication failed: %s\", string(body))}\n\t\t}\n\t\tif opcode != cqlOpAuthOk && opcode != cqlOpReady {\n\t\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: fmt.Errorf(\"unexpected opcode: %d\", opcode)}\n\t\t}\n\t}\n\n\t// Step 4: 发送测试查询\n\tqueryBody := cqlLongString(\"SELECT cluster_name FROM system.local\")\n\t// 添加 consistency level (ONE=1)\n\tqueryBody = append(queryBody, 0x00, 0x01) // flags=0, consistency=ONE\n\tif err := cqlSend(conn, cqlOpQuery, queryBody); err != nil {\n\t\tstate.IncrementTCPFailedPacketCount()\n\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}\n\t}\n\topcode, body, err = cqlRecv(conn)\n\tif err != nil {\n\t\tstate.IncrementTCPFailedPacketCount()\n\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}\n\t}\n\tif err := validateCQLQueryResponse(opcode, body); err != nil {\n\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: err}","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/cassandra.go#L127-L163","documentation":"Guard in doCassandraAuth: after sending the SASL PLAIN auth token, the next CQL frame carried neither the AUTH_SUCCESS nor the ERROR opcode expected at this point in the handshake. An unexpected protocol opcode means the server response does not match the CQL conversation state.","triggerScenarios":"doCassandraAuth reads the post-SASL response; opcode is not cqlOpAuthOk, cqlOpReady, or cqlOpError — e.g. a protocol violation or an intermediary answering with an unexpected frame.","commonSituations":"Target is not really Cassandra (a proxy/load balancer speaking something else); protocol version mismatch causing garbled framing; server extension or fork deviating from the native protocol v3/v4 spec.","solutions":["Note the opcode value in the error and compare with the Cassandra native protocol spec to identify the reply type.","Confirm the target really is a Cassandra node and no TCP proxy is rewriting the stream.","Try pinning a different CQL protocol version so framing/opcode negotiation matches the server."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"res := doCassandraAuth(conn, cred, state)\nif !res.Success && strings.HasPrefix(res.Error.Error(), \"unexpected opcode\") {\n    conn.Close()\n    conn = dial(...) // fresh connection resyncs framing\n}","preventionTips":["Confirm the target IP:port is a Cassandra native-transport endpoint, not a proxy or another service.","Pin a mutually supported CQL protocol version.","Always reconnect (never keep reading) after an unclassifiable frame to avoid desync."],"tags":["cassandra","cql","protocol","opcode"],"backgroundTag":"unexpected-response-shape","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}