AlistGo/alist · error
failed to EncryptData: %w
Error message
failed to EncryptData: %w
What it means
Thrown by Crypt.Put when the rclone crypt cipher fails to wrap the input stream with EncryptData. EncryptData builds an encrypting reader over the file streamer; it fails when the cipher was constructed with incompatible parameters for streaming encryption or when the input stream cannot be adapted (e.g. nil/invalid streamer characteristics after the path already resolved fine). The upload aborts before any data reaches the remote.
Source
Thrown at drivers/crypt/driver.go:376
func (d *Crypt) Remove(ctx context.Context, obj model.Obj) error {
remoteActualPath, err := d.getActualPathForRemote(obj.GetPath(), obj.IsDir())
if err != nil {
return fmt.Errorf("failed to convert path to remote path: %w", err)
}
return op.Remove(ctx, d.remoteStorage, remoteActualPath)
}
func (d *Crypt) Put(ctx context.Context, dstDir model.Obj, streamer model.FileStreamer, up driver.UpdateProgress) error {
dstDirActualPath, err := d.getActualPathForRemote(dstDir.GetPath(), true)
if err != nil {
return fmt.Errorf("failed to convert path to remote path: %w", err)
}
// Encrypt the data into wrappedIn
wrappedIn, err := d.cipher.EncryptData(streamer)
if err != nil {
return fmt.Errorf("failed to EncryptData: %w", err)
}
// doesn't support seekableStream, since rapid-upload is not working for encrypted data
streamOut := &stream.FileStream{
Obj: &model.Object{
ID: streamer.GetID(),
Path: streamer.GetPath(),
Name: d.cipher.EncryptFileName(streamer.GetName()),
Size: d.cipher.EncryptedSize(streamer.GetSize()),
Modified: streamer.ModTime(),
IsFolder: streamer.IsDir(),
},
Reader: wrappedIn,
Mimetype: "application/octet-stream",
WebPutAsTask: streamer.NeedStore(),
ForceStreamUpload: true,
Exist: streamer.GetExist(),
}View on GitHub (pinned to 843d9dc814)
Solutions
- Re-enter password and salt in the admin UI and re-save the crypt storage so a fresh cipher is built
- Upgrade AList to a consistent version (bundled rclone library matches driver code)
- Check the wrapped error message — 'bad password' style errors mean credentials; stream errors mean the FileStreamer setup
- Re-create the crypt storage if the existing record keeps failing after credential re-entry
Defensive patterns
Strategy: try-catch
Validate before calling
// Before upload, verify the cipher works on a tiny buffer
if _, err := d.cipher.EncryptData(bytes.NewReader([]byte("probe"))); err != nil {
return fmt.Errorf("cipher unusable, re-enter credentials: %w", err)
} Try / catch
if err := d.Put(ctx, dstDir, streamer, up); err != nil {
if strings.Contains(err.Error(), "failed to EncryptData") {
// cipher/credential problem: re-save storage with fresh password+salt, then retry upload
return fmt.Errorf("encryption failed, refresh crypt credentials and retry: %w", err)
}
return err
} Prevention
- Re-enter crypt credentials after major version upgrades
- Never hand-edit obscured password/salt values in the DB
- Run a small test upload after configuring or upgrading a crypt storage
When it happens
Trigger: Uploading a file through the crypt mount when the cipher's configuration makes stream encryption fail — most commonly a corrupted or wrong-version password/salt pair that slipped past NewCipher, or an upstream rclone library change where EncryptData rejects the stream wrapper (nil reader, unsupported ReaderAt expectations).
Common situations: AList/rclone-library version mismatch after upgrade while old obscured credentials remain in the DB; storage record hand-edited so the cipher is half-initialized; very old crypt storage created by a much earlier AList version.
Related errors
- failed to create Cipher: %w
- not get file info
- 123 offline download cannot target the root directory, pick
- file_id is required
- same-name dirs cannot be Put
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/6b87e40c13e2744b.
Report an issue: GitHub.