@cryptotaxi247 / kubo / commits / 566f8ba63

keys: skip bad keys when listing (#11115)

Change the `ipfs key list` behavior to log an error and continue listing keys when a key cannot be read from the keystore or decoded. Closes: #11102

Andrew Gillis committed Jan 7, 2026 at 09:56 UTC 566f8ba63f185a64ec676f1b1af5e3a61b6e174c
3 files changed +17 -9
core/commands/keystore.go
+2 -2
@@ -458,7 +458,7 @@ var keyListCmd = &cmds.Command{
458 Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
459 keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
460 if err != nil {
461 - return err
461 + return fmt.Errorf("cannot get key encoder: %w", err)
462 }
463
464 api, err := cmdenv.GetApi(env, req)
@@ -468,7 +468,7 @@ var keyListCmd = &cmds.Command{
468
469 keys, err := api.Key().List(req.Context)
470 if err != nil {
471 - return err
471 + return fmt.Errorf("listing keys failed: %w", err)
472 }
473
474 list := make([]KeyOutput, 0, len(keys))
core/coreapi/key.go
+10 -7
@@ -29,7 +29,7 @@ type key struct {
29 func newKey(name string, pid peer.ID) (*key, error) {
30 p, err := path.NewPath("/ipns/" + ipns.NameFromPeer(pid).String())
31 if err != nil {
32 - return nil, err
32 + return nil, fmt.Errorf("cannot create new key: %w", err)
33 }
34 return &key{
35 name: name,
@@ -121,34 +121,37 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) {
121
122 keys, err := api.repo.Keystore().List()
123 if err != nil {
124 - return nil, err
124 + return nil, fmt.Errorf("cannot list keys in keystore: %w", err)
125 }
126
127 sort.Strings(keys)
128
129 - out := make([]coreiface.Key, len(keys)+1)
129 + out := make([]coreiface.Key, 1, len(keys)+1)
130 out[0], err = newKey("self", api.identity)
131 if err != nil {
132 return nil, err
133 }
134
135 - for n, k := range keys {
135 + for _, k := range keys {
136 privKey, err := api.repo.Keystore().Get(k)
137 if err != nil {
138 - return nil, err
138 + log.Errorf("cannot get key from keystore: %s", err)
139 + continue
140 }
141
142 pubKey := privKey.GetPublic()
143
144 pid, err := peer.IDFromPublicKey(pubKey)
145 if err != nil {
145 - return nil, err
146 + log.Errorf("cannot decode public key: %s", err)
147 + continue
148 }
149
148 - out[n+1], err = newKey(k, pid)
150 + k, err := newKey(k, pid)
151 if err != nil {
152 return nil, err
153 }
154 + out = append(out, k)
155 }
156 return out, nil
157 }
docs/changelogs/v0.40.md
+5
@@ -12,6 +12,7 @@ This release was brought to you by the [Shipyard](https://ipshipyard.com/) team.
12 - [🔦 Highlights](#-highlights)
13 - [Routing V1 HTTP API now exposed by default](#routing-v1-http-api-now-exposed-by-default)
14 - [Track total size when adding pins](#track-total-size-when-adding-pins)
15 + - [Skip bad keys when listing](#skip_bad_keys_when_listing)
16 - [📦️ Dependency updates](#-dependency-updates)
17 - [📝 Changelog](#-changelog)
18 - [👨‍👩‍👧‍👦 Contributors](#-contributors)
@@ -33,6 +34,10 @@ Example output:
34 Fetched/Processed 336 nodes (83 MB)
35 ```
36
37 +#### Skip bad keys when listing
38 +
39 +Change the `ipfs key list` behavior to log an error and continue listing keys when a key cannot be read from the keystore or decoded.
40 +
41 #### 📦️ Dependency updates
42
43 - update `go-libp2p` to [v0.46.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.46.0)