ipfs/kubo · error

saving old key in keystore (%v)

Error message

saving old key in keystore (%v)

What it means

After decoding the old private key, doRotate writes it into the repo keystore under the --old-key name via keystore.Put. Failure here is wrapped as "saving old key in keystore (%v)" — typically a keystore write error (bad name, filesystem failure). The rotate aborts before the config is modified, so the node identity is unchanged.

Source

Thrown at core/commands/keystore.go:808

			options.Key.Type(algorithm),
		})
	} else {
		identity, err = config.CreateIdentity(out, []options.KeyGenerateOption{
			options.Key.Type(algorithm),
		})
	}
	if err != nil {
		return fmt.Errorf("creating identity (%v)", err)
	}

	// Save old identity to keystore
	oldPrivKey, err := cfg.Identity.DecodePrivateKey("")
	if err != nil {
		return fmt.Errorf("decoding old private key (%v)", err)
	}
	keystore := repo.Keystore()
	if err := keystore.Put(oldKey, oldPrivKey); err != nil {
		return fmt.Errorf("saving old key in keystore (%v)", err)
	}

	// Update identity
	cfg.Identity = identity

	// Write config file to repo
	if err = repo.SetConfig(cfg); err != nil {
		return fmt.Errorf("saving new key to config (%v)", err)
	}
	return nil
}

func keyOutputListEncoders() cmds.EncoderFunc {
	return cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, list *KeyOutputList) error {
		withID, _ := req.Options["l"].(bool)

		tw := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0)
		for _, s := range list.Keys {

View on GitHub (pinned to 329838acdf)

Solutions

  1. Use a simple alphanumeric keystore name for --old-key (e.g. old-self-2024)
  2. Check $IPFS_PATH/keystore permissions and free disk space (`df -h`)
  3. Retry after fixing the filesystem issue; rotate is safe to retry since config is only written after this step succeeds
  4. Inspect the wrapped (%v) message for the exact keystore error

Example fix

// before
ipfs key rotate --old-key="my/old key"
// after
ipfs key rotate --old-key=old-key-2024
Defensive patterns

Strategy: validation

Validate before calling

name="old-self-2024"
case "$name" in *[!A-Za-z0-9_-]*) echo "invalid keystore name"; exit 1;; esac
df -h "$IPFS_PATH" | awk 'NR==2 {exit ($5+0 >= 95) ? 1 : 0}' || { echo 'disk almost full'; exit 1; }

Type guard

func safeKeystoreName(name string) bool {
    if name == "" || name == "self" { return false }
    for _, r := range name {
        if !(r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || r == '-' || r == '_') {
            return false
        }
    }
    return true
}

Try / catch

if err := doRotate(...); err != nil {
    if strings.Contains(err.Error(), "saving old key in keystore") {
        // safe to retry: config untouched; fix name/disk/permissions first
    }
}

Prevention

When it happens

Trigger: The chosen oldKey name fails keystore naming rules (invalid characters); filesystem permission or disk-full errors writing $IPFS_PATH/keystore/<name>; keystore file locked/unreadable.

Common situations: Passing a name with slashes or illegal characters via --old-key; repo directory owned by another user; read-only filesystem; full disk.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/12ddbaf60c9cb3b5. Report an issue: GitHub.