kopia/kopia · warning
unable to persist password
Error message
unable to persist password
What it means
OnSuccess persistently saves the connected server's password after a successful connect. This error wraps a failure of s.PersistPassword (keyring or file strategy), meaning the password could not be stored for future passwordless reconnects — the connect itself succeeded.
Solutions
- Unlock or initialize the OS keyring (e.g. unlock gnome-keyring/login keychain) and retry the connect
- Check write permissions on the directory containing the config file
- Select a different persistence strategy (e.g. file-based) via the passwordpersist options if keyring is unavailable
- Persist nothing and provide the password at each connect as a fallback
Defensive patterns
Strategy: fallback
Validate before calling
// check whether the keyring is usable before attempting persistence
if _, err := keyring.Get(service, "probe"); err != nil && !errors.Is(err, keyring.ErrNotFound) {
log.Printf("keyring unavailable, password will not persist: %v", err)
} Type guard
null
Prevention
- Ensure a running, unlocked keyring daemon before connecting
- Keep the config directory writable by the running user
- Allow users to opt into non-persistent passwords on headless systems
When it happens
Trigger: Calling OnSuccess (directly or via connect commands) when the chosen PasswordStorage's PersistPassword fails: OS keyring locked/unavailable, file write denied, or an unsupported platform strategy.
Common situations: macOS/Linux keyring locked or no keyring daemon running; read-only or unwritable config directory; disk full; headless CI without a keyring service.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- error retrieving password from OS keyring, the keyring may…
- blob configuration
- blob configuration
- BLOB not found
- callback failed for
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/353d5e9989d98a54.
Report an issue: GitHub.
Appendix: source
Thrown at internal/passwordpersist/passwordpersist.go:43
// PersistPassword persists a password, returns ErrUnsupported or fatal errors.
PersistPassword(ctx context.Context, configFile, password string) error
// DeletePassword deletes any persisted password, returns fatal errors.
DeletePassword(ctx context.Context, configFile string) error
}
// OnSuccess is a helper that persists the given (configFile,password) if the provided err is nil
// and deletes any persisted password otherwise.
func OnSuccess(ctx context.Context, err error, s Strategy, configFile, password string) error {
if err != nil {
if err2 := s.DeletePassword(ctx, configFile); err2 != nil {
log(ctx).Infof("unable to delete persistent password: %v", err2)
}
return err
}
return errors.Wrap(s.PersistPassword(ctx, configFile, password), "unable to persist password")
}
View on GitHub (pinned to 82495e54b5)