micro/go-micro · error

Failed to list objects

Error message

Failed to list objects

What it means

The NATS JetStream KV store wrapper calls bucket.Keys(nats.IgnoreDeletes()) to enumerate keys in a bucket and wraps any failure (other than ErrKeyNotFound) with 'Failed to list objects'. It means the JetStream KV bucket could not be enumerated — the keys request to the JetStream stream failed. This surfaces when listing table contents via natsKeys/microKeys.

Source

Thrown at store/nats-js-kv/nats.go:445

	}

	keys, _, err := n.getKeys(bucket, table, toS(key, prefix), toS(key, suffix))

	return keys, err
}

func (n *natsStore) microKeys(bucket nats.KeyValue, table, prefix, suffix string) ([]string, error) {
	_, keys, err := n.getKeys(bucket, table, prefix, suffix)

	return keys, err
}

func (n *natsStore) getKeys(bucket nats.KeyValue, table string, prefix, suffix string) ([]string, []string, error) {
	names, err := bucket.Keys(nats.IgnoreDeletes())
	if errors.Is(err, nats.ErrKeyNotFound) {
		return []string{}, []string{}, nil
	} else if err != nil {
		return []string{}, []string{}, errors.Wrap(err, "Failed to list objects")
	}

	natsKeys := make([]string, 0, len(names))
	microKeys := make([]string, 0, len(names))

	for _, k := range names {
		mkey, ok := n.MicroKeyFilter(table, k, prefix, suffix)
		if !ok {
			continue
		}

		natsKeys = append(natsKeys, k)
		microKeys = append(microKeys, mkey)
	}

	return natsKeys, microKeys, nil
}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Verify the NATS server is reachable and JetStream is enabled (jetstream {} in nats-server config).
  2. Check that the KeyValue bucket exists with the configured name (nats kv ls / nats kv info <bucket>).
  3. Confirm the account/credentials have read permissions on the KV stream.
  4. Reconnect or recreate the store so a fresh KeyValue handle is obtained.
  5. Inspect the wrapped cause in the error chain (errors.Unwrap) for the specific JetStream API error.

Example fix

// before
kv, _ := js.KeyValue(ctx, "mybucket") // stale after bucket recreation
keys, err := store.List()
// after
kv, err := js.KeyValue(ctx, "mybucket")
if errors.Is(err, nats.ErrBucketNotFound) {
	kv, err = js.CreateKeyValue(ctx, nats.KeyValueConfig{Bucket: "mybucket"})
}
keys, err := store.List()
Defensive patterns

Strategy: retry

Validate before calling

// before listing
resp, err := js.AccountInfo(ctx)
if err != nil || !resp.JetStreamAccountLimits.MaxStreamLimitsExceeded {
	// jetstream reachable
}
_, err = js.KeyValue(ctx, bucketName)
if err != nil { // bucket missing/unreachable: recreate or reconfigure store first }

Type guard

func isKeyListErr(err error) bool {
	return err != nil && !errors.Is(err, nats.ErrKeyNotFound)
}

Try / catch

keys, err := store.List()
if err != nil {
	if isTransient(err) { // reconnect nats and retry
		nc, _ := nats.Connect(url); defer store.Close(); store = newStore(nc)
		return store.List()
	}
	return err
}

Prevention

When it happens

Trigger: Calling List/Read with a prefix on a store backed by nats-js-kv when the underlying KeyValue bucket's Keys() call fails: bucket/stream deleted, NATS server unavailable, no permission to read the stream, or a JetStream API error/timeout.

Common situations: NATS server restarted or bucket dropped while the service holds a stale handle; bucket name changed between config versions; NATS account lacks JetStream read permissions; JetStream temporarily disabled or resource limits (stream limits) exceeded.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/0e54a1d706354ab3. Report an issue: GitHub.