AlistGo/alist · error

failed to obfuscate password: %w

Error message

failed to obfuscate password: %w

What it means

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.

Source

Thrown at drivers/crypt/driver.go:48

	cipher        *rcCrypt.Cipher
	remoteStorage driver.Driver
}

const obfuscatedPrefix = "___Obfuscated___"

func (d *Crypt) Config() driver.Config {
	return config
}

func (d *Crypt) GetAddition() driver.Additional {
	return &d.Addition
}

func (d *Crypt) Init(ctx context.Context) error {
	//obfuscate credentials if it's updated or just created
	err := d.updateObfusParm(&d.Password)
	if err != nil {
		return fmt.Errorf("failed to obfuscate password: %w", err)
	}
	err = d.updateObfusParm(&d.Salt)
	if err != nil {
		return fmt.Errorf("failed to obfuscate salt: %w", err)
	}

	isCryptExt := regexp.MustCompile(`^[.][A-Za-z0-9-_]{2,}$`).MatchString
	if !isCryptExt(d.EncryptedSuffix) {
		return fmt.Errorf("EncryptedSuffix is Illegal")
	}
	d.FileNameEncoding = utils.GetNoneEmpty(d.FileNameEncoding, "base64")
	d.EncryptedSuffix = utils.GetNoneEmpty(d.EncryptedSuffix, ".bin")

	op.MustSaveDriverStorage(d)

	//need remote storage exist
	storage, err := fs.GetStorage(d.RemotePath, &fs.GetStoragesArgs{})
	if err != nil {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Provide a non-empty password for the Crypt storage (required to derive the cipher anyway)
  2. If you truly want passphrase-less filenames, this driver does not support it — choose another approach
  3. After setting the password once, it is stored obfuscated and subsequent Inits skip the failing path

Example fix

// before
{
  "password": "",
  "remote_path": "/cloud"
}

// after
{
  "password": "my-secret-passphrase",
  "remote_path": "/cloud"
}
Defensive patterns

Strategy: validation

Validate before calling

// before saving a Crypt storage: require a non-empty password (unless already obfuscated)
if cfg.Password == "" || !strings.HasPrefix(cfg.Password, "___Obfuscated___") {
    if strings.TrimSpace(cfg.Password) == "" {
        return errors.New("crypt storage requires a non-empty password")
    }
}

Type guard

func hasUsableCryptSecret(v string) bool {
    return strings.HasPrefix(v, "___Obfuscated___") || strings.TrimSpace(v) != ""
}

Try / catch

if err := cryptStorage.Init(ctx); err != nil {
    if strings.Contains(err.Error(), "failed to obfuscate password") {
        // empty/unencodable password: prompt user for a value, then re-init
        return errors.New("crypt password is empty or invalid; set a non-empty password")
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/b7a30bf9400e0135. Report an issue: GitHub.