{"record":{"id":"b7a30bf9400e0135","repo":"AlistGo/alist","slug":"failed-to-obfuscate-password-w","errorCode":null,"errorMessage":"failed to obfuscate password: %w","messagePattern":"failed to obfuscate password: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/crypt/driver.go","lineNumber":48,"sourceCode":"\tcipher        *rcCrypt.Cipher\n\tremoteStorage driver.Driver\n}\n\nconst obfuscatedPrefix = \"___Obfuscated___\"\n\nfunc (d *Crypt) Config() driver.Config {\n\treturn config\n}\n\nfunc (d *Crypt) GetAddition() driver.Additional {\n\treturn &d.Addition\n}\n\nfunc (d *Crypt) Init(ctx context.Context) error {\n\t//obfuscate credentials if it's updated or just created\n\terr := d.updateObfusParm(&d.Password)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to obfuscate password: %w\", err)\n\t}\n\terr = d.updateObfusParm(&d.Salt)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to obfuscate salt: %w\", err)\n\t}\n\n\tisCryptExt := regexp.MustCompile(`^[.][A-Za-z0-9-_]{2,}$`).MatchString\n\tif !isCryptExt(d.EncryptedSuffix) {\n\t\treturn fmt.Errorf(\"EncryptedSuffix is Illegal\")\n\t}\n\td.FileNameEncoding = utils.GetNoneEmpty(d.FileNameEncoding, \"base64\")\n\td.EncryptedSuffix = utils.GetNoneEmpty(d.EncryptedSuffix, \".bin\")\n\n\top.MustSaveDriverStorage(d)\n\n\t//need remote storage exist\n\tstorage, err := fs.GetStorage(d.RemotePath, &fs.GetStoragesArgs{})\n\tif err != nil {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/crypt/driver.go#L30-L66","documentation":"Initialization error in the Crypt driver. On Init, plaintext credentials are obfuscated for at-rest storage using rclone's obscure.Obscure (AES-CTR + base64, prefixed with ___Obfuscated___). If Obscure returns an error — in practice, when the input string is empty, since rclone rejects obscuring an empty value — the password cannot be secured and Init fails with this wrapped message.","triggerScenarios":"Creating or updating a Crypt storage with an empty password (and it is not already prefixed with ___Obfuscated___); rclone's obscure also fails if the value cannot be encrypted, but the empty-input case is the realistic trigger. Values already starting with the obfuscation prefix are passed through untouched.","commonSituations":"Setting up a Crypt storage and leaving the password field blank intending 'no encryption'; clearing the password during a config update; automation writing an empty string into the password field.","solutions":["Provide a non-empty password for the Crypt storage (required to derive the cipher anyway)","If you truly want passphrase-less filenames, this driver does not support it — choose another approach","After setting the password once, it is stored obfuscated and subsequent Inits skip the failing path"],"exampleFix":"// before\n{\n  \"password\": \"\",\n  \"remote_path\": \"/cloud\"\n}\n\n// after\n{\n  \"password\": \"my-secret-passphrase\",\n  \"remote_path\": \"/cloud\"\n}","handlingStrategy":"validation","validationCode":"// before saving a Crypt storage: require a non-empty password (unless already obfuscated)\nif cfg.Password == \"\" || !strings.HasPrefix(cfg.Password, \"___Obfuscated___\") {\n    if strings.TrimSpace(cfg.Password) == \"\" {\n        return errors.New(\"crypt storage requires a non-empty password\")\n    }\n}","typeGuard":"func hasUsableCryptSecret(v string) bool {\n    return strings.HasPrefix(v, \"___Obfuscated___\") || strings.TrimSpace(v) != \"\"\n}","tryCatchPattern":"if err := cryptStorage.Init(ctx); err != nil {\n    if strings.Contains(err.Error(), \"failed to obfuscate password\") {\n        // empty/unencodable password: prompt user for a value, then re-init\n        return errors.New(\"crypt password is empty or invalid; set a non-empty password\")\n    }\n}","preventionTips":["Mark the crypt password field as required in config UIs","Never write empty strings into credential fields during automation","Remember stored values carry the ___Obfuscated___ prefix and skip re-obscuring"],"tags":["alist","crypt","configuration","credentials","init"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}