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

  1. Filter nils out of the slice before passing it to Config: build with append only when non-nil.
  2. Use a constructor that always returns a non-nil Service or returns an error.
  3. 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

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


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)