gofiber/fiber · critical

fiber: service %q is nil

Error message

fiber: service %q is nil

What it means

Returned by shutdownServices (services.go:124) when the app's internal state map contains a nil Service under a given key during termination. This is a defensive guard: app.state.setService only stores successfully-started services, so a nil entry indicates memory/state corruption or a bug in a custom Service whose Start mutated shared state.

Source

Thrown at services.go:124

		}

		errs = append(errs, fmt.Errorf("service %s start: %w", srv.String(), err))
	}
	return errors.Join(errs...)
}

// shutdownServices Handles the shutdown process of services for the current application.
// Iterates over all the started services in reverse order and tries to terminate them,
// returning an error if any error occurs.
func (app *App) shutdownServices(ctx context.Context) error {
	if app.state.ServicesLen() == 0 {
		return nil
	}

	var errs []error
	for key, srv := range app.state.Services() {
		if srv == nil {
			return fmt.Errorf("fiber: service %q is nil", key)
		}
		if err := ctx.Err(); err != nil {
			// Context is canceled, do a best effort to terminate the services.
			errs = append(errs, fmt.Errorf("service %s terminate: %w", srv.String(), err))
			continue
		}

		err := srv.Terminate(ctx)
		if err != nil {
			// Best effort to terminate the services.
			errs = append(errs, fmt.Errorf("service %s terminate: %w", srv.String(), err))
			continue
		}

		// Remove the service from the State
		app.state.deleteService(srv)
	}
	return errors.Join(errs...)

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Avoid touching app.state or app.configured.Services directly; use only fiber.Config.Services.
  2. Ensure no goroutine sets app.state entries concurrently with Shutdown.
  3. If forking, audit setService/deleteService to guarantee non-nil invariants.
  4. Report as a Fiber bug if it reproduces on unmodified upstream with a minimal example.

Example fix

// before: directly mutating app state (unsafe)
app.state.setService(nil)

// after: never inject nil; only registered services enter state
app := fiber.New(fiber.Config{Services: []fiber.Service{realSvc}})
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: app.shutdownServices iterates app.state.Services() (services.go:122) and finds a nil value. Triggered during app.Shutdown after services were started. Requires the state map to have been populated with nil, which should not happen via normal APIs.

Common situations: Concurrent misuse of app state, a fork that injects nil into app.state.services, or a race between setService/deleteService during shutdown. In correct upstream usage this is effectively unreachable.

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/222dd4c632fe7670.json. Report an issue: GitHub.