gofiber/fiber · error
fiber: service at index
Error message
fiber: service at index %d is nil
What it means
Returned by validateConfiguredServices() (via validateServicesSlice) when any element of fiber.Config.Services is nil. This runs during App startup validation, before the server begins listening. Fiber refuses to start a service slice with gaps because the Start/Terminate loop would dereference nil.
Solutions
- Filter nils out of the slice before passing it to Config: build with append only when non-nil.
- Use a constructor that always returns a non-nil Service or returns an error.
- Add a unit test asserting every element of cfg.Services is non-nil.
Example fix
// before — conditional nil in slice
var metrics fiber.Service
if cfg.Metrics {
metrics = metricsSvc
}
app := fiber.New(fiber.Config{Services: []fiber.Service{db, metrics}})
// -> fiber: service at index 1 is nil
// after — append only non-nil
svcs := []fiber.Service{db}
if cfg.Metrics {
svcs = append(svcs, metricsSvc)
}
app := fiber.New(fiber.Config{Services: svcs}) Defensive patterns
Strategy: validation
Validate before calling
// Build the Services slice defensively, skipping nils.
func buildServices(flags map[string]bool, mk map[string]func() fiber.Service) []fiber.Service {
out := make([]fiber.Service, 0, len(flags))
for name, on := range flags {
if !on { continue }
if s := mk[name](); s != nil { out = append(out, s) }
}
return out
} Type guard
func allServicesNonNil(s []fiber.Service) bool {
for _, s := range s { if s == nil { return false } }
return true
} Prevention
- Build the Services slice with conditional append, never positional nils.
- Assert in a unit test that every element is non-nil before fiber.New().
- Make service factories return (Service, error), never nil.
When it happens
Trigger: Configuring app with fiber.New(fiber.Config{Services: []fiber.Service{someSvc, nil}}) — a nil slipped into the slice via a conditional append (e.g., `Services: []fiber.Service{a, maybeNil}` where maybeNil was nil).
Common situations: Building the Services slice conditionally and forgetting to filter nils (e.g., `var db fiber.Service; if enabled { db = ... }; Services: []fiber.Service{db}`); a service factory returning nil on a feature flag; refactoring that removed an initializer but left the slice slot.
Related errors
- fiber: Config.RegexHandler must be a non-nil function
- fiber: Config.RegexHandler must not return nil
- fiber: service at index
- basicauth: charset must be UTF-8
- context canceled while starting service
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/20873288e19964f4.
Report an issue: GitHub.
Appendix: 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 a105acad6c)