{"record":{"id":"6f90f868427762a6","repo":"glanceapp/glance","slug":"hashing-password-for-user-s-v","errorCode":null,"errorMessage":"hashing password for user %s: %v","messagePattern":"hashing password for user (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/glance.go","lineNumber":89,"sourceCode":"\t\tapp.usernameHashToUsername = make(map[string]string)\n\t\tapp.failedAuthAttempts = make(map[string]*failedAuthAttempt)\n\t\tapp.RequiresAuth = true\n\n\t\tfor username := range config.Auth.Users {\n\t\t\tuser := config.Auth.Users[username]\n\t\t\tusernameHash, err := computeUsernameHash(username, secretBytes)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"computing username hash for user %s: %v\", username, err)\n\t\t\t}\n\t\t\tapp.usernameHashToUsername[string(usernameHash)] = username\n\n\t\t\tif user.PasswordHashString != \"\" {\n\t\t\t\tuser.PasswordHash = []byte(user.PasswordHashString)\n\t\t\t\tuser.PasswordHashString = \"\"\n\t\t\t} else {\n\t\t\t\thashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"hashing password for user %s: %v\", username, err)\n\t\t\t\t}\n\n\t\t\t\tuser.Password = \"\"\n\t\t\t\tuser.PasswordHash = hashedPassword\n\t\t\t}\n\t\t}\n\n\t\tapp.authSecretKey = secretBytes\n\t}\n\n\t//\n\t// Init themes\n\t//\n\n\tif !config.Theme.DisablePicker {\n\t\tthemeKeys := make([]string, 0, 2)\n\t\tthemeProps := make([]*themeProperties, 0, 2)\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/glance.go#L71-L107","documentation":"Startup fails when bcrypt.GenerateFromPassword errors while hashing a user's plaintext password (config users with a plain `password` field, i.e. no pre-computed password-hash). bcrypt only errors when the password exceeds 72 bytes, so this almost always means a configured password longer than 72 characters.","triggerScenarios":"A user entry in config.Auth.Users with a `password:` longer than 72 bytes and no `password-hash` field, causing bcrypt.GenerateFromPassword to return bcrypt.PasswordTooLongError (Go's x/crypto >= 0.x behavior).","commonSituations":"Pasting a long passphrase or a full base64/hex string as the login password; using machine-generated 128-char secrets as the glance login password.","solutions":["Shorten the user's password to 72 bytes or fewer","Better: pre-hash and supply `password-hash` instead of `password` (e.g. hash the long secret with sha256 first, then use that digest as the password, or store a bcrypt hash in password-hash)","Keep long secrets in a password manager and use a shorter typed password for glance"],"exampleFix":"# before\nauth:\n  users:\n    admin:\n      password: \"<80+-character-passphrase>\"\n# after\nauth:\n  users:\n    admin:\n      password: \"shorter-passphrase<=72-bytes\"\n","handlingStrategy":"validation","validationCode":"// Enforce bcrypt's 72-byte limit before glance hashes\nfor name, u := range cfg.Auth.Users {\n    if u.PasswordHashString == \"\" && len(u.Password) > 72 {\n        return fmt.Errorf(\"user %s password exceeds 72 bytes\", name)\n    }\n}\n","typeGuard":null,"tryCatchPattern":"Catch at startup and point at the named user (the %s in the message); require a shorter password or a password-hash value — do not silently truncate.","preventionTips":["Keep glance login passwords under 72 bytes","Prefer `password-hash` (bcrypt) for machine-generated long secrets","Add a config lint step for auth users before deploy"],"tags":["auth","bcrypt","config","startup"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}