{"record":{"id":"acf4443c0c556dc3","repo":"AlistGo/alist","slug":"can-t-find-remote-storage-w-acf444","errorCode":null,"errorMessage":"can't find remote storage: %w","messagePattern":"can't find remote storage: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"drivers/crypt/driver.go","lineNumber":67,"sourceCode":"\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,\n\t\t\"filename_encryption\":       d.FileNameEnc,\n\t\t\"directory_name_encryption\": d.DirNameEnc,\n\t\t\"filename_encoding\":         d.FileNameEncoding,\n\t\t\"suffix\":                    d.EncryptedSuffix,\n\t\t\"pass_bad_blocks\":           \"\",\n\t}\n\tc, err := rcCrypt.NewCipher(config)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create Cipher: %w\", err)\n\t}","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/crypt/driver.go#L49-L85","documentation":"Thrown during Crypt driver initialization when the configured RemotePath cannot be resolved to a mounted storage via fs.GetStorage. The crypt driver is a wrapper that encrypts/decrypts data on top of an existing storage mount, so it must locate that underlying mount before it can build its cipher and serve requests. If the remote storage is missing, renamed, or the path is malformed, Init fails and the storage cannot be added.","triggerScenarios":"Calling driver Init (adding/refreshing the crypt storage in AList admin UI) with a RemotePath whose mount path does not match any mounted storage, e.g. RemotePath '/cloud' when the actual mount is '/onedrive'. Also triggered when the underlying storage was deleted or its mount path changed after the crypt storage was created, or when RemotePath is set to a sub-path of a mount that fails to load.","commonSituations":"Typos in the remote_path field; creating the crypt storage before creating the target storage; deleting/renaming the underlying mount; forgetting that RemotePath must be the mount path (with optional subfolder) of an already-added storage; case-sensitivity mismatches in the mount path.","solutions":["Verify the RemotePath field exactly matches an existing storage mount path (check Storage list in admin UI) and save the crypt storage again","Create/add the underlying storage first, confirm it is healthy (status showing work), then add the crypt storage on top of it","If the underlying storage was renamed, update RemotePath to the new mount path","Check server logs for the wrapped fs.GetStorage error to see the exact path that failed to resolve"],"exampleFix":"// before\n{\n  \"remote_path\": \"/clouddrive\",   // no storage mounted at /clouddrive\n  \"password\": \"...\"\n}\n// after\n{\n  \"remote_path\": \"/onedrive\",     // matches an existing healthy storage mount\n  \"password\": \"...\"\n}","handlingStrategy":"validation","validationCode":"// Before adding the crypt storage, confirm a healthy storage exists at RemotePath\nstorages, _ := adminStorageList() // fs.GetStorages or admin API\nmount := strings.SplitN(remotePath, \"/\", 3)[1] // first path segment\nfound := false\nfor _, s := range storages {\n    if strings.Trim(s.MountPath, \"/\") == mount && s.Status == \"work\" { found = true }\n}\nif !found { return errors.New(\"add the underlying storage at \" + mount + \" first\") }","typeGuard":null,"tryCatchPattern":"if err := cryptStorage.Init(ctx); err != nil {\n    if strings.Contains(err.Error(), \"can't find remote storage\") {\n        // config problem: fix RemotePath, do not retry\n        log.Printf(\"crypt mount misconfigured: %v\", err)\n    }\n    return err\n}","preventionTips":["Always create and verify the underlying storage before adding the crypt storage on top","Use the exact mount path from the storage list; copy-paste instead of retyping","If the underlying storage is renamed or deleted, update or remove the crypt storage in the same change","Automate a health check that asserts every crypt storage's RemotePath still resolves to a mounted storage"],"tags":["crypt","config","storage-mount","initialization"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}