{"record":{"id":"1ff33c744b1774a0","repo":"AlistGo/alist","slug":"encryptedsuffix-is-illegal","errorCode":null,"errorMessage":"EncryptedSuffix is Illegal","messagePattern":"EncryptedSuffix is Illegal","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/crypt/driver.go","lineNumber":57,"sourceCode":"\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 {\n\t\treturn fmt.Errorf(\"can't find remote storage: %w\", err)\n\t}\n\td.remoteStorage = storage\n\n\tp, _ := strings.CutPrefix(d.Password, obfuscatedPrefix)\n\tp2, _ := strings.CutPrefix(d.Salt, obfuscatedPrefix)\n\tconfig := configmap.Simple{\n\t\t\"password\":                  p,\n\t\t\"password2\":                 p2,","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/crypt/driver.go#L39-L75","documentation":"Initialization validation in the Crypt driver. The encrypted_suffix option (e.g. .bin) must match ^[.][A-Za-z0-9-_]{2,}$: begin with a dot, then at least two characters drawn from letters, digits, hyphen, or underscore. Validation runs before the .bin default is applied, so anything failing the regex — including an empty value — aborts Init with this message.","triggerScenarios":"Setting encrypted_suffix to a value that is empty, lacks the leading dot (\"bin\"), is too short (\".b\"), or contains characters outside [A-Za-z0-9-_] (\".bin.enc\", \".b!n\", \".bin files\"). Note the default \".bin\" comes from the Addition tag, so blank only fails when the field is explicitly cleared/emptied in a context where the default was not re-applied.","commonSituations":"Trying a multi-part suffix like \".enc.gz\" (dot is not allowed after the first); using a one-character suffix like \".x\"; copying suffix conventions from rclone crypt where different rules apply; explicit empty value from API-driven storage creation.","solutions":["Use a suffix matching the pattern: leading dot plus 2+ characters of letters/digits/hyphen/underscore — \".bin\", \".enc\", \".c1\"","Avoid additional dots or special characters in the suffix","Leave the field untouched to inherit the \".bin\" default rather than blanking it"],"exampleFix":"// before\n\"encrypted_suffix\": \".bin.enc\"\n\n// after\n\"encrypted_suffix\": \".bin\"","handlingStrategy":"validation","validationCode":"var encryptedSuffixRe = regexp.MustCompile(`^[.][A-Za-z0-9-_]{2,}$`)\n\nif !encryptedSuffixRe.MatchString(cfg.EncryptedSuffix) {\n    return fmt.Errorf(\"encrypted_suffix %q must be a dot followed by 2+ of [A-Za-z0-9-_]\", cfg.EncryptedSuffix)\n}","typeGuard":"func isValidEncryptedSuffix(s string) bool {\n    return regexp.MustCompile(`^[.][A-Za-z0-9-_]{2,}$`).MatchString(s)\n}","tryCatchPattern":"if err := cryptStorage.Init(ctx); err != nil {\n    if strings.Contains(err.Error(), \"EncryptedSuffix is Illegal\") {\n        cfg.EncryptedSuffix = \".bin\" // reset to default and re-init once\n    }\n}","preventionTips":["Validate the suffix with the same regex in the config UI before submission","Forbid extra dots and spaces in the suffix input","Leave the field untouched to inherit the .bin default rather than blanking it"],"tags":["alist","crypt","configuration","validation","init"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}