gofiber/fiber · critical
fiber: service at index %d is nil
Error message
fiber: service at index %d is nil
What it means
Returned by validateServicesSlice (services.go:40) when the config.Services slice passed to the Fiber app contains a nil entry. Fiber refuses to boot because a nil Service has no Start/Terminate methods and would panic later. The index in the message identifies exactly which slice position is nil.
Source
Thrown at services.go:40
State(ctx context.Context) (string, error)
// Terminate terminates the service, returning an error if it fails.
Terminate(ctx context.Context) error
}
// hasConfiguredServices Checks if there are any services for the current application.
func (app *App) hasConfiguredServices() bool {
return len(app.configured.Services) > 0
}
func (app *App) validateConfiguredServices() error {
return validateServicesSlice(app.configured.Services)
}
func validateServicesSlice(services []Service) error {
for idx, srv := range services {
if srv == nil {
return fmt.Errorf("fiber: service at index %d is nil", idx)
}
}
return nil
}
// initServices If the app is configured to use services, this function registers
// a post shutdown hook to shutdown them after the server is closed.
// This function panics if there is an error starting the services.
func (app *App) initServices() {
if !app.hasConfiguredServices() {
return
}
if err := app.startServices(app.servicesStartupCtx()); err != nil {
panic(err)
}
}
View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Filter nils out of the Services slice before passing it to fiber.New: only append non-nil services.
- Fix the service factory to never return nil; return an error instead and handle it.
- Use a guard helper: services = append(services, svc) only when svc != nil.
Example fix
// before
services := []fiber.Service{redisSvc, nil, metricsSvc}
app := fiber.New(fiber.Config{Services: services})
// after: build defensively
var services []fiber.Service
for _, s := range []fiber.Service{redisSvc, maybeMetricsSvc, metricsSvc} {
if s != nil {
services = append(services, s)
}
}
app := fiber.New(fiber.Config{Services: services}) Defensive patterns
Strategy: validation
Validate before calling
services := []fiber.Service{a, b, c}
nonNil := services[:0]
for _, s := range services {
if s != nil {
nonNil = append(nonNil, s)
}
}
app := fiber.New(fiber.Config{Services: nonNil}) Type guard
func isNonNilServices(s []fiber.Service) bool {
for _, srv := range s {
if srv == nil { return false }
}
return true
} Prevention
- Build the Services slice with append guarded by != nil.
- Service factories should return (Service, error), never nil.
- Run validateConfiguredServices() in a bootstrap test.
When it happens
Trigger: Configuring app with fiber.Config{Services: []fiber.Service{someService, nil}} and then calling app.New() (validateConfiguredServices runs during construction). Also triggered by app.startServices in initServices.
Common situations: Conditional service registration that appends a nil when a flag is off (e.g. svc := maybeNewService(); Services: []Service{svc}), or a factory returning nil on partial failure. Refactoring that leaves a placeholder nil in a service list.
Related errors
- failed to parse client CA certificate from %q
- favicon: file size exceeds max bytes %d
- context canceled while starting service %s: %w
- service %s start: %w
- fiber: service %q is nil
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/20873288e19964f4.json.
Report an issue: GitHub.