gofiber/fiber · critical
fiber: service at index %d is nil
Error message
fiber: service at index %d is nil
What it means
During fiber.New(Config{...}), validateConfiguredServices iterates Config.Services and returns this error if any entry is nil; fiber.New then panics on that error. Services are user-supplied background workers (DB pools, clients) that Fiber starts/stops with the app, and a nil slot is always a caller bug.
Source
Thrown at app.go:733
// Define hooks
app.hooks = newHooks(app)
// Define mountFields
app.mountFields = newMountFields(app)
// Define state
app.state = newState()
// Override config if provided
if len(config) > 0 {
app.config = config[0]
}
// Initialize configured before defaults are set
app.configured = app.config
if err := app.validateConfiguredServices(); err != nil {
panic(err)
}
// Override default values
if app.config.BodyLimit <= 0 {
app.config.BodyLimit = DefaultBodyLimit
}
if app.config.MaxRanges <= 0 {
app.config.MaxRanges = DefaultMaxRanges
}
if app.config.Concurrency <= 0 {
app.config.Concurrency = DefaultConcurrency
}
if app.config.ReadBufferSize <= 0 {
app.config.ReadBufferSize = DefaultReadBufferSize
}
if app.config.WriteBufferSize <= 0 {
app.config.WriteBufferSize = DefaultWriteBufferSize
}View on GitHub (pinned to a105acad6c)
Solutions
- Audit the Config.Services slice construction and drop nil entries before passing to fiber.New.
- Replace any nil service with a real initialized instance or omit it.
- Add a helper that filters nils: slices.DeleteFunc(services, func(s fiber.Service) bool { return s == nil }).
- Make service factories return an error instead of nil so the failure is explicit.
Example fix
// before
services := []fiber.Service{dbPool, maybeNilClient}
app := fiber.New(fiber.Config{Services: services})
// after
services := []fiber.Service{}
if dbPool != nil { services = append(services, dbPool) }
if maybeNilClient != nil { services = append(services, maybeNilClient) }
app := fiber.New(fiber.Config{Services: services}) Defensive patterns
Strategy: validation
Validate before calling
// Filter nil services before constructing the app
func buildServices(svcs []fiber.Service) []fiber.Service {
out := svcs[:0:0]
for _, s := range svcs {
if s == nil { continue }
out = append(out, s)
}
return out
} Try / catch
// Defer-recover around fiber.New in bootstrap to convert panic to error
func newApp(cfg fiber.Config) (app *fiber.App, err error) {
defer func() {
if r := recover(); r != nil { err = fmt.Errorf("fiber.New: %v", r) }
}()
app = fiber.New(cfg)
return app, nil
} Prevention
- Make service factories return (Service, error), never nil.
- Write a startup test that constructs the app config and asserts no panic.
- Keep Config.Services construction in one place to audit easily.
When it happens
Trigger: Calling fiber.New(fiber.Config{Services: []fiber.Service{nil, someSvc}}) or building the Services slice conditionally and appending nil when a constructor fails.
Common situations: Constructing the Services slice with optional entries where one is unset; refactor that introduces a nil-producing factory; conditional registration like if cond { services = append(services, nil) }.
Related errors
- fiber: service at index %d is nil
- tls: AutoCertManager cannot be combined with CertFile/CertKe
- context canceled while starting service %s: %w
- service %s start: %w
- fiber: Config.RegexHandler return type must support MatchStr
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/a5057f8e85f9656a.
Report an issue: GitHub.