{"id":"c420f1ac0889e83c","repo":"go-redis/redis","slug":"failed-to-authenticate-w","errorCode":null,"errorMessage":"failed to authenticate: %w","messagePattern":"failed to authenticate: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"redis.go","lineNumber":817,"sourceCode":"\t\t// the server does not support the HELLO command.\n\t\t// The server may be a redis-server that does not support the HELLO command,\n\t\t// or it could be DragonflyDB or a third-party redis-proxy. They all respond\n\t\t// with different error string results for unsupported commands, making it\n\t\t// difficult to rely on error strings to determine all results.\n\t\tcn.GetStateMachine().Transition(pool.StateClosed)\n\t\treturn initErr\n\t} else {\n\t\thelloFallbackToRESP2 = c.opt.Protocol == 3\n\t\tif password != \"\" {\n\t\t\t// Try legacy AUTH command if HELLO failed.\n\t\t\tif username != \"\" {\n\t\t\t\tinitErr = conn.AuthACL(ctx, username, password).Err()\n\t\t\t} else {\n\t\t\t\tinitErr = conn.Auth(ctx, password).Err()\n\t\t\t}\n\t\t\tif initErr != nil {\n\t\t\t\tcn.GetStateMachine().Transition(pool.StateClosed)\n\t\t\t\treturn fmt.Errorf(\"failed to authenticate: %w\", initErr)\n\t\t\t}\n\t\t}\n\t}\n\tif helloFallbackToRESP2 {\n\t\tc.disableCSCServing(ctx, \"HELLO 3 was rejected and the connection negotiated RESP2\")\n\t}\n\n\t// trackingEnabled reports whether THIS pool connection must issue\n\t// CLIENT TRACKING ON during init. True when CSC (SharedTracking) is enabled:\n\t// the shared cache is fed by per-connection tracking + the background\n\t// drainer. Once CSC serving stops (owner Close, GC cleanup, or drainer\n\t// damping), new and re-inited conns skip tracking — nothing consumes the\n\t// pushes into the cache anymore.\n\ttrackingEnabled := !helloFallbackToRESP2 && !cn.IsPubSub() && c.cscTrackingRequested()\n\tif trackingEnabled && c.cscConnInitGen(cn.GetID()) == 0 {\n\t\t// First initialization establishes generation 1. Reinitialization\n\t\t// already bumped and evicted through onCscReinit before replacing the\n\t\t// socket, so it must not bump a second time here.","sourceCodeStart":799,"sourceCodeEnd":835,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/redis.go#L799-L835","documentation":"Thrown when HELLO negotiation fell back (server does not support HELLO) and the legacy AUTH/AUTH ACL fallback then failed. This only runs when a password is set: the client tries HELLO first, and on rejection issues AUTH; if AUTH itself errors, the connection is closed and wrapped with this message.","triggerScenarios":"Server rejects HELLO (older redis-server < 6, or DragonflyDB/proxy without HELLO) AND Password != \"\" AND the subsequent AUTH (or AUTH ACL when Username is also set) returns a redis error such as WRONGPASS or invalid username.","commonSituations":"Wrong password configured; ACL user deleted or disabled; connecting with a Username to a server that requires AUTH without username but the password is wrong; password contains characters that were mangled by shell/config escaping; rotated credential not yet propagated.","solutions":["Verify the password is correct with redis-cli AUTH (or AUTH user pass for ACL).","If using ACL, confirm the user exists and has permissions on the target DB (ACL GETUSER).","Check for shell/config escaping issues around special characters in the password.","If the password is correct, ensure the server actually requires legacy AUTH (older server) vs. HELLO-based auth."],"exampleFix":"// before\nopt := &redis.Options{Addr: addr, Username: \"app\", Password: wrongPass}\n\n// after\nopt := &redis.Options{Addr: addr, Username: \"app\", Password: correctPass}","handlingStrategy":"validation","validationCode":"// Verify credentials out-of-band before relying on the client.\nrc := redis.NewClient(&redis.Options{Addr: addr, Username: user, Password: pass})\nif err := rc.Ping(ctx).Err(); err != nil {\n    return fmt.Errorf(\"auth pre-check failed: %w\", err)\n}\nrc.Close()","typeGuard":null,"tryCatchPattern":"if err := client.Ping(ctx).Err(); err != nil {\n    var pe *redis.errorString // go-redis may expose auth error helpers\n    if redis.IsAuthErr(err) || strings.Contains(err.Error(), \"WRONGPASS\") {\n        // surface as a credential problem\n    }\n}","preventionTips":["Treat passwords as secrets managed outside source control; rotate via a controlled process.","When migrating to ACL, create and test the new user before switching the client config.","Quote-protect passwords with special characters in config files and shells."],"tags":["authentication","auth","config"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}