gastownhall/beads · error
failed to encrypt password: %w
Error message
failed to encrypt password: %w
What it means
After ensuring the credential key exists, addFederationPeer encrypts the peer's password with AES-GCM via encryptPassword; this wraps any failure from that encryption. Encryption itself only fails if the in-memory key is missing (should not happen after ensureCredentialKey) or the crypto primitives/nonce generation fail.
Source
Thrown at internal/storage/dolt/credentials.go:287
})
}
func (s *DoltStore) addFederationPeer(ctx context.Context, peer *storage.FederationPeer) error {
// Validate peer name
if err := validatePeerName(peer.Name); err != nil {
return fmt.Errorf("invalid peer name: %w", err)
}
// Encrypt password before storing
var encryptedPwd []byte
var err error
if peer.Password != "" {
if err := s.ensureCredentialKey(ctx); err != nil {
return fmt.Errorf("failed to initialize credential key: %w", err)
}
encryptedPwd, err = s.encryptPassword(peer.Password)
if err != nil {
return fmt.Errorf("failed to encrypt password: %w", err)
}
}
// Upsert the peer credentials
_, err = s.execContext(ctx, `
INSERT INTO federation_peers (name, remote_url, username, password_encrypted, sovereignty)
VALUES (?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
remote_url = VALUES(remote_url),
username = VALUES(username),
password_encrypted = VALUES(password_encrypted),
sovereignty = VALUES(sovereignty),
updated_at = CURRENT_TIMESTAMP
`, peer.Name, peer.RemoteURL, peer.Username, encryptedPwd, peer.Sovereignty)
if err != nil {
return fmt.Errorf("failed to add federation peer: %w", err)
}View on GitHub (pinned to 71377f2769)
Solutions
- Retry the operation; transient crypto/rand failures usually indicate entropy starvation — fix the host entropy source (e.g. ensure /dev/urandom availability in the container).
- Verify the key file is exactly 32 bytes; a corrupt key file means re-initialization is needed (re-add peer credentials afterwards).
- Avoid constructing DoltStore manually in tests; use the standard constructor and call ensureCredentialKey before encryption.
Defensive patterns
Strategy: retry
Try / catch
err := store.AddFederationPeer(ctx, peer)
if err != nil && strings.Contains(err.Error(), "failed to encrypt password") {
// transient crypto/rand failure — retry once after backoff
time.Sleep(100 * time.Millisecond)
err = store.AddFederationPeer(ctx, peer)
} Prevention
- Ensure adequate entropy in constrained containers
- Keep the 32-byte key file intact; never hand-edit it
- Construct stores via the standard constructor to avoid nil-key races
When it happens
Trigger: Calling AddFederationPeer with a non-empty peer.Password when encryptWithKey fails — AES cipher/GCM construction error or crypto/rand nonce read failure — or when the key was concurrently reset to nil between ensureCredentialKey and encryptPassword.
Common situations: System entropy exhaustion (crypto/rand read failure in constrained containers); key length corruption (key file truncated to non-32 bytes bypassing the 32-byte check upstream); race conditions on a manually constructed store.
Related errors
- failed to initialize credential key: %w
- failed to decrypt password: %w
- failed to re-encrypt password for peer %s: %w
- no store is open for this workspace
- not found
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/6b41ddf3363be645.
Report an issue: GitHub.