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

  1. Audit the Config.Services slice construction and drop nil entries before passing to fiber.New.
  2. Replace any nil service with a real initialized instance or omit it.
  3. Add a helper that filters nils: slices.DeleteFunc(services, func(s fiber.Service) bool { return s == nil }).
  4. 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

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


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/a5057f8e85f9656a. Report an issue: GitHub.