micro/go-micro · error

source not found: %s

Error message

source not found: %s

What it means

The NATS config source reads a key from a JetStream KV bucket. If the key exists but its value is nil or empty, Read returns 'source not found: <key>'. Note that nats.ErrKeyNotFound itself returns (nil, nil), so this error specifically means the key was found but holds no data.

Source

Thrown at config/source/nats/nats.go:40

// DefaultBucket is the bucket that nats keys will be assumed to have if you
// haven't specified one.
var (
	DefaultBucket = "default"
	DefaultKey    = "micro_config"
)

func (n *nats) Read() (*source.ChangeSet, error) {
	e, err := n.kv.Get(n.key)
	if err != nil {
		if err == natsgo.ErrKeyNotFound {
			return nil, nil
		}
		return nil, err
	}

	if e.Value() == nil || len(e.Value()) == 0 {
		return nil, fmt.Errorf("source not found: %s", n.key)
	}

	cs := &source.ChangeSet{
		Data:      e.Value(),
		Format:    n.opts.Encoder.String(),
		Source:    n.String(),
		Timestamp: time.Now(),
	}
	cs.Checksum = cs.Sum()

	return cs, nil
}

func (n *nats) Write(cs *source.ChangeSet) error {
	_, err := n.kv.Put(n.key, cs.Data)
	if err != nil {
		return err
	}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Put non-empty config data into the KV key before loading: nats kv put <bucket> <key> @config.json
  2. Verify the configured bucket/key options (source.WithContext with your key/bucket values) point at the intended entry
  3. Check upstream writers so the key is never written with empty content
  4. Handle the empty-source case in code: fall back to defaults when Read returns this error

Example fix

// before
kv.Put("micro_config", []byte{}) // later: source not found: micro_config
// after
cfg, _ := os.ReadFile("config.json")
kv.Put("micro_config", cfg)
Defensive patterns

Strategy: validation

Validate before calling

entry, err := kv.Get(key)
if err != nil || entry == nil || len(entry.Value()) == 0 {
    return errors.New("nats config key missing or empty: " + key)
}

Type guard

func hasConfigValue(kv natsgo.KeyValue, key string) bool {
    e, err := kv.Get(key)
    return err == nil && e != nil && len(e.Value()) > 0
}

Prevention

When it happens

Trigger: Calling Read (during config load or Sync) when the KV entry for the configured key exists with an empty/nil value — e.g. the key was created empty or someone Put an empty payload.

Common situations: Bootstrapping a fresh KV bucket where the config key was never populated; a deploy pipeline writing an empty config file; a typo'd bucket/key combination resolving to an empty placeholder entry.

Related errors


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