micro/go-micro · info
ErrNotFound
ErrNotFound
Error message
not found
What it means
model.ErrNotFound is the sentinel the model package returns when a queried record does not exist (service rows, registry entries, etc.). Callers should compare with errors.Is(err, model.ErrNotFound) to distinguish 'no such record' from real failures.
Source
Thrown at model/model.go:11
// Package model is an interface for structured data storage with schema awareness.
package model
import (
"context"
"errors"
)
var (
// ErrNotFound is returned when a record doesn't exist.
ErrNotFound = errors.New("not found")
// ErrDuplicateKey is returned when a record with the same key already exists.
ErrDuplicateKey = errors.New("duplicate key")
// ErrNotRegistered is returned when a table has not been registered.
ErrNotRegistered = errors.New("table not registered")
// DefaultModel is the default model.
DefaultModel Model = NewModel()
)
// Model is a structured data storage interface.
type Model interface {
// Init initializes the model.
Init(...Option) error
// Register registers a struct type as a table.
Register(v interface{}, opts ...RegisterOption) error
// Create inserts a new record. Returns ErrDuplicateKey if key exists.
Create(ctx context.Context, v interface{}) error
// Read retrieves a record by key into v. Returns ErrNotFound if missing.
Read(ctx context.Context, key string, v interface{}) errorView on GitHub (pinned to 24529f1404)
Solutions
- Check errors.Is(err, model.ErrNotFound) and handle it as an expected 'absent' outcome, not a crash.
- Verify the record key/name and that the service was registered before lookup.
- Retry the lookup with backoff if the record may appear shortly (eventual consistency).
- Seed required records in tests before the code under exercise reads them.
Example fix
// before
svc, err := reg.GetService("foo")
if err != nil { return err } // crashes on 'not found'
// after
svc, err := reg.GetService("foo")
if errors.Is(err, model.ErrNotFound) { return nil // treat as absent
}
if err != nil { return err } Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
func isNotFound(err error) bool { return errors.Is(err, model.ErrNotFound) } Try / catch
svc, err := reg.GetService(name)
switch {
case errors.Is(err, model.ErrNotFound):
return nil, nil // absent is expected
case err != nil:
return nil, err
} Prevention
- Always use errors.Is against model.ErrNotFound, never string comparison
- Register/seed records before code that reads them
- Handle the absent case explicitly in lookup paths
- Distinguish stale-cache lookups from genuine typos by logging the queried key
When it happens
Trigger: Reading a service by name that was never created or was deleted; registry next/Load iterating a table where the requested key is absent; a stale cache referencing a removed service.
Common situations: Race between service deregistration and lookup; typos in service names; querying before registration completed; tests asserting on services not seeded in the store.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/a0353dd4ca50fdb6.
Report an issue: GitHub.