gofiber/fiber · error
fiber: service is nil
Error message
fiber: service %q is nil
What it means
Returned by shutdownServices() when iterating app.state.Services() (the set of successfully started services) and a value is nil. app.state should only contain non-nil services (set via app.state.setService after a successful Start), so a nil here indicates internal corruption or a custom State mutation.
Solutions
- Do not write to app.state outside the framework's start/terminate lifecycle.
- If writing tests, use the public Services() read path and avoid injecting nils.
- Treat an occurrence as a corruption signal and audit any addon/middleware that touches State.
Defensive patterns
Strategy: validation
Validate before calling
// Never write to State outside the framework; if you must, validate.
func stateHealthy(app *fiber.App) error {
for k, s := range app.State().Services() {
if s == nil { return fmt.Errorf("nil service in state at %q", k) }
}
return nil
} Prevention
- Treat app.state as framework-private.
- Avoid test code that injects nils into State.
When it happens
Trigger: Something wrote a nil into the State's service map after Start completed — e.g., a custom addon or test harness calling an unexported setter, or a race on shutdown. Under the normal Listen/Shutdown flow this is unreachable because setService only runs on successful Start.
Common situations: Test code that manipulates app.state directly; a fork that adds custom State mutation; memory corruption. Practically a defensive guard that should never fire in production.
Related errors
- context canceled while starting service
- fiber: service at index
- service terminate
- state: service not found!
- [CORS] Invalid origin format after normalization:
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/222dd4c632fe7670.
Report an issue: GitHub.
Appendix: source
Thrown at services.go:124
}
errs = append(errs, fmt.Errorf("service %s start: %w", srv.String(), err))
}
return errors.Join(errs...)
}
// shutdownServices Handles the shutdown process of services for the current application.
// Iterates over all the started services in reverse order and tries to terminate them,
// returning an error if any error occurs.
func (app *App) shutdownServices(ctx context.Context) error {
if app.state.ServicesLen() == 0 {
return nil
}
var errs []error
for key, srv := range app.state.Services() {
if srv == nil {
return fmt.Errorf("fiber: service %q is nil", key)
}
if err := ctx.Err(); err != nil {
// Context is canceled, do a best effort to terminate the services.
errs = append(errs, fmt.Errorf("service %s terminate: %w", srv.String(), err))
continue
}
err := srv.Terminate(ctx)
if err != nil {
// Best effort to terminate the services.
errs = append(errs, fmt.Errorf("service %s terminate: %w", srv.String(), err))
continue
}
// Remove the service from the State
app.state.deleteService(srv)
}
return errors.Join(errs...)View on GitHub (pinned to a105acad6c)