micro/go-micro · warning · ErrNotFound
not found
Error message
not found
What it means
ErrNotFound is the store package's sentinel for a missing key: Get/Read (and the registry helpers built on it) return it when the requested key does not exist in the store. It is a normal, expected outcome for cache-miss style flows, not a crash — the interface contract expects callers to branch on it.
Source
Thrown at store/store.go:14
// Package store is an interface for distributed data storage.
// The design document is located at https://github.com/micro/development/blob/master/design/store.md
package store
import (
"errors"
"time"
"encoding/json"
)
var (
// ErrNotFound is returned when a key doesn't exist.
ErrNotFound = errors.New("not found")
// DefaultStore is the file store (persists to ~/micro/store/).
DefaultStore Store = NewStore()
)
// Store is a data storage interface.
type Store interface {
// Init initializes the store. It must perform any required setup on the backing storage implementation and check that it is ready for use, returning any errors.
Init(...Option) error
// Options allows you to view the current options.
Options() Options
// Read takes a single key name and optional ReadOptions. It returns matching []*Record or an error.
Read(key string, opts ...ReadOption) ([]*Record, error)
// Write() writes a record to the store, and returns an error if the record was not written.
Write(r *Record, opts ...WriteOption) error
// Delete removes the record with the corresponding key from the store.
Delete(key string, opts ...DeleteOption) error
// List returns any keys that match, or an empty list with no error if none matched.
List(opts ...ListOption) ([]string, error)View on GitHub (pinned to 24529f1404)
Solutions
- Check errors.Is(err, store.ErrNotFound) and treat it as a cache miss: write the record or return a 404-style response
- Verify you are reading from the same database/table/namespace the key was written to
- If the key should exist, check TTL options passed at Write time and whether another process deleted it
Example fix
// before
recs, err := s.Read("user:42")
if err != nil { return err } // 500 on a simple miss
// after
recs, err := s.Read("user:42")
if err == store.ErrNotFound { return http.StatusNotFound }
if err != nil { return err } Defensive patterns
Strategy: type-guard
Validate before calling
_, err := st.Read(key)
if err == store.ErrNotFound { /* treat as miss */ } Type guard
func IsNotFound(err error) bool { return err == store.ErrNotFound || errors.Is(err, store.ErrNotFound) } Try / catch
recs, err := st.Read(key)
if IsNotFound(err) { return nil, ErrKeyMissing }
if err != nil { return nil, err } Prevention
- Write before read in init flows; seed expected keys
- Set sensible TTLs and handle expiry as a miss
- Confirm database/table/namespace options match between writer and reader
When it happens
Trigger: store.Read("key") on a key never written; TestRegistryServiceCheckMissingService path where a service name lookup finds nothing; Load/next iterating a registry/store and exhausting entries.
Common situations: Reading before writing (ordering bug), TTL expiry of a previously written record, wrong database/table/namespace configured so the key lives elsewhere, deleted entries from another process.
Related errors
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/9ab3d8f09e1e5637.
Report an issue: GitHub.