{"record":{"id":"2c253146373da723","repo":"shadow1ng/fscan","slug":"sasl-authenticate-error-d","errorCode":null,"errorMessage":"SASL authenticate error: %d","messagePattern":"SASL authenticate error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/kafka.go","lineNumber":132,"sourceCode":"\t\t\t}\n\t\t}\n\n\t\t// SaslAuthenticate: PLAIN token = \\x00user\\x00pass (api_key=36, api_version=0)\n\t\ttoken := []byte(\"\\x00\" + cred.Username + \"\\x00\" + cred.Password)\n\t\tauthBody := kafkaBytes(token)\n\t\tif err := kafkaSend(conn, 36, 0, authBody); err != nil {\n\t\t\tstate.IncrementTCPFailedPacketCount()\n\t\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}\n\t\t}\n\t\tresp, err = kafkaRecv(conn)\n\t\tif err != nil {\n\t\t\tstate.IncrementTCPFailedPacketCount()\n\t\t\treturn &AuthResult{Success: false, ErrorType: classifyKafkaErrorType(err), Error: err}\n\t\t}\n\t\tif len(resp) >= 2 {\n\t\t\tcode := int16(binary.BigEndian.Uint16(resp[:2]))\n\t\t\tif code != 0 {\n\t\t\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: fmt.Errorf(\"SASL authenticate error: %d\", code)}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Step 3: Metadata 请求验证连接 (api_key=3, api_version=0)\n\t// body: [topics_array] -> empty array = request all topics\n\tmetaBody := []byte{0x00, 0x00, 0x00, 0x00} // empty topics array + allow_auto_topic_creation=false\n\tif err := kafkaSend(conn, 3, 0, metaBody); err != nil {\n\t\tstate.IncrementTCPFailedPacketCount()\n\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}\n\t}\n\t_, err = kafkaRecv(conn)\n\tif err != nil {\n\t\tstate.IncrementTCPFailedPacketCount()\n\t\treturn &AuthResult{Success: false, ErrorType: ErrorTypeNetwork, Error: err}\n\t}\n\n\tstate.IncrementTCPSuccessPacketCount()","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/kafka.go#L114-L150","documentation":"doKafkaAuth parses the SaslAuthenticate response and treats a non-zero big-endian int16 error_code in the first 2 bytes as an authentication failure. The broker accepted the handshake but rejected the PLAIN credentials token (wrong user/pass) or the auth state is illegal. The code is included in the wrapped message.","triggerScenarios":"doKafkaAuth: SaslAuthenticate request (api_key=36, PLAIN token \\x00user\\x00pass) receives a response with non-zero error code — typically code 58 (SaslAuthenticationFailed) for bad credentials.","commonSituations":"Wrong username/password in the credential list (expected during brute-force scanning); broker requires SCRAM instead of PLAIN so the token is rejected; credentials valid only for a different listener/mechanism; account locked or ACL-denied user.","solutions":["Verify credentials manually with kcat/kafka-console-producer to confirm they are wrong vs the mechanism being wrong","Check sasl.enabled.mechanisms on the broker; if only SCRAM is enabled, PLAIN tokens will always fail","Treat code 58 as an expected 'bad credential' result in scan output rather than an unexpected error","Ensure JAAS/user ACLs permit the user on the target listener"],"exampleFix":"// before\nif code != 0 {\n    return &AuthResult{Success: false, ErrorType: ErrorTypeAuth, Error: fmt.Errorf(\"SASL authenticate error: %d\", code)}\n}\n// after\nif code != 0 {\n    et := ErrorTypeAuth\n    if code == 58 { et = ErrorTypeAuth } // explicit bad-credentials mapping\n    return &AuthResult{Success: false, ErrorType: et, Error: fmt.Errorf(\"SASL authenticate error: %d\", code)}\n}","handlingStrategy":"try-catch","validationCode":"// Verify credentials out-of-band before scanning:\n// kcat -b broker:9092 -X security.protocol=SASL_PLAINTEXT -X sasl.mechanisms=PLAIN -X sasl.username=u -X sasl.password=p -L","typeGuard":"func isBadCredentials(code int16) bool { return code == 58 } // SaslAuthenticationFailed","tryCatchPattern":"res := plugin.Scan(info, config, state)\nfor _, r := range res.AuthResults {\n    if r.Error != nil && strings.Contains(r.Error.Error(), \"SASL authenticate error\") {\n        if isBadCredentials(extractCode(r.Error)) {\n            log.Println(\"kafka: invalid credential pair\")\n        } else {\n            log.Printf(\"kafka: auth state error: %v\", r.Error)\n        }\n    }\n}","preventionTips":["Validate credentials with kcat before bulk scanning","Check sasl.enabled.mechanisms; SCRAM-only brokers reject PLAIN tokens","Treat code 58 as an expected scan outcome, not an exceptional error","Confirm the user exists and has ACLs on the target listener"],"tags":["kafka","sasl","authentication","credentials"],"backgroundTag":"authentication-failed","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}