gofiber/fiber · critical
state: service not found!
Error message
state: service not found!
What it means
Raised by MustGetService[T Service] (state.go:315) when GetService[T] returns ok==false. Services are stored under a hashed key: servicePrefix (a per-process random hash, servicesStatePrefix + uuid, generated in init at state.go:16) concatenated with hex(srv.String()) via serviceKey (state.go:241-244). A service is only placed into State by App.startServices (services.go:100) AFTER srv.Start() returns nil for entries in fiber.Config.Services. So the panic means one of: the service was never configured, Start() failed so it was never setService'd, the lookup key != srv.String(), or the type parameter T doesn't match the registered concrete type.
Source
Thrown at state.go:315
}
return true
})
return length
}
// GetService returns a service present in the application's State.
func GetService[T Service](s *State, key string) (T, bool) {
srv, ok := GetState[T](s, s.serviceKey(key))
return srv, ok
}
// MustGetService returns a service present in the application's State.
// It panics if the service is not found.
func MustGetService[T Service](s *State, key string) T {
srv, ok := GetService[T](s, key)
if !ok {
panic("state: service not found!")
}
return srv
}
View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Ensure the service is listed in fiber.Config{Services: []fiber.Service{...}} and that its Start() returns nil — startServices only setService's on success (services.go:98-101).
- Make the lookup key byte-identical to srv.String(); use one shared constant at registration and retrieval.
- Use fiber.GetService[T] (comma-ok) to handle absence gracefully instead of MustGetService.
- Confirm you query the same App whose startServices ran — services live on that app's app.state, keyed by its per-process servicePrefix.
Example fix
// before — panics if service is absent, not started, key mismatches, or wrong type
svc := fiber.MustGetService[*Cache](app.State(), "cache")
// after — derive the key from the service's String() and guard the lookup
const cacheKey = "cache" // == cache.String()
// registration: fiber.Config{Services: []fiber.Service{cache}}
srv, ok := fiber.GetService[*Cache](app.State(), cacheKey)
if !ok {
return fmt.Errorf("service %q not available (not configured, failed to start, or wrong type)", cacheKey)
} Defensive patterns
Strategy: validation
Validate before calling
const key = "cache" // must equal cache.String()
srv, ok := fiber.GetService[*Cache](app.State(), key)
if !ok {
return fmt.Errorf("service %q not available (not configured, Start failed, key mismatch, or wrong type)", key)
} Type guard
func serviceAvailable[T fiber.Service](s *fiber.State, key string) bool {
_, ok := fiber.GetService[T](s, key)
return ok
} Try / catch
defer func() {
if r := recover(); r != nil {
if msg, _ := r.(string); strings.Contains(msg, "service not found") {
log.Printf("service lookup failed: %v", r)
return
}
panic(r)
}
}()
svc := fiber.MustGetService[*Cache](app.State(), "cache") Prevention
- Derive lookup keys from srv.String() via a shared constant so registration and retrieval can't drift.
- Always add the service to Config.Services and surface/log every Start() error so silent start failures don't hide as 'not found'.
- Prefer fiber.GetService[T] over MustGetService[T] in request handlers.
- Query services only on the App instance that ran startServices — the servicePrefix is per-process and per-State.
When it happens
Trigger: Call fiber.MustGetService[*Cache](app.State(), "cache") when: Cache isn't in app.Config().Services; its Start() returned an error so setService was never called (services.go:98-101); the key passed differs from the service's String() return value; or T differs from the registered concrete type. Also triggered by querying a service on a different App/State instance than the one that ran startServices.
Common situations: Forgetting to add the service to Config.Services; a mismatch between the service's String() implementation and the lookup literal; a service that failed to start silently (error swallowed) or an app boot path that skipped initServices; querying from a second App instance; refactoring String() without updating call sites.
Related errors
- state: dependency not found!
- runtime.Goexit() called in handler or server panic
- fiber: service %q is nil
- shutdown: graceful timeout has been reached, exiting
- shutdown: server is not running
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/eee5b09cc1cf4bf7.json.
Report an issue: GitHub.