AlistGo/alist · error
failed to re-encrypt node passphrase: %w
Error message
failed to re-encrypt node passphrase: %w
What it means
DirectMove failed to re-encrypt the node's passphrase for the destination parent (reencryptNodePassphrase, util.go:815-847): it derives source-parent and destination-parent keyrings and re-wraps the link's NodePassphrase key packet. Failures are parent-link fetch errors, keyring derivation failures (shared folder / signature issues), or PGP errors in reencryptKeyPacket — undecryptable armored passphrase, wrong session-key packet, or encryption with the destination keyring failing.
Source
Thrown at drivers/proton_drive/util.go:778
encryptedName, err := d.encryptFileName(ctx, srcObj.GetName(), dstParentLinkID)
if err != nil {
return nil, fmt.Errorf("failed to encrypt filename: %w", err)
}
newHash, err := d.generateNameHash(ctx, srcObj.GetName(), dstParentLinkID)
if err != nil {
return nil, fmt.Errorf("failed to generate new hash: %w", err)
}
originalHash, err := d.getOriginalNameHash(srcLink)
if err != nil {
return nil, fmt.Errorf("failed to get original hash: %w", err)
}
// Re-encrypt node passphrase for new parent context
reencryptedPassphrase, err := d.reencryptNodePassphrase(ctx, srcLink, dstParentLinkID)
if err != nil {
return nil, fmt.Errorf("failed to re-encrypt node passphrase: %w", err)
}
moveReq := MoveRequest{
ParentLinkID: dstParentLinkID,
NodePassphrase: reencryptedPassphrase,
Name: encryptedName,
NameSignatureEmail: d.MainShare.Creator,
Hash: newHash,
OriginalHash: originalHash,
ContentHash: nil,
// *** Causes rejection ***
/* NodePassphraseSignature: srcLink.NodePassphraseSignature, */
}
//fmt.Printf("DEBUG MoveRequest validation:\n")
//fmt.Printf(" Name length: %d\n", len(moveReq.Name))
//fmt.Printf(" Hash: %s\n", moveReq.Hash)View on GitHub (pinned to 843d9dc814)
Solutions
- Check the wrapped error to localize: 'failed to get source/destination parent keyring' vs 'failed to re-encrypt key packet'
- For keyring errors, re-initialize the driver (fresh address/share keys) and retry
- Verify read+decrypt access on BOTH source parent and destination parent (list both folders)
- If NodePassphrase is empty/invalid, re-fetch the source link with full metadata
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight both parents must be listable (keyrings derivable)
if _, err := d.List(ctx, srcParent); err != nil { return err }
if _, err := d.List(ctx, dstDir); err != nil { return err }
if srcLink.NodePassphrase == "" { return fmt.Errorf("source link lacks passphrase") } Try / catch
if err := d.DirectMove(ctx, src, dst); err != nil {
if strings.Contains(err.Error(), "failed to re-encrypt node passphrase") {
// keyring access problem on source or destination parent:
// re-init driver (fresh address/share keys), verify share membership, retry once
}
} Prevention
- Re-initialize the driver after Proton password resets so keyrings are fresh
- Verify decrypt access on both source and destination parents before cross-share moves
- Re-fetch the source link to guarantee a valid armored NodePassphrase
When it happens
Trigger: Moving between shares where either parent keyring cannot be derived; srcLink.NodePassphrase empty or not a valid armored PGP split message; account keys revoked after password reset so DecryptSessionKey fails; destination in a share not re-shared to this account's keys.
Common situations: Cross-share moves (personal -> shared or shared -> shared); mounts surviving a Proton password reset with stale keyrings; moving items whose passphrase was rotated by another client while cached.
Related errors
- failed to get original hash: %w
- cannot move to same parent directory
- move operation failed with code: %d
- failed to find destination: %w
- same-name files cannot be moved
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/3efae01812d62bff.
Report an issue: GitHub.