gofiber/fiber · error

fiber: service is nil

Error message

fiber: service %q is nil

What it means

Returned by shutdownServices() when iterating app.state.Services() (the set of successfully started services) and a value is nil. app.state should only contain non-nil services (set via app.state.setService after a successful Start), so a nil here indicates internal corruption or a custom State mutation.

Solutions

  1. Do not write to app.state outside the framework's start/terminate lifecycle.
  2. If writing tests, use the public Services() read path and avoid injecting nils.
  3. Treat an occurrence as a corruption signal and audit any addon/middleware that touches State.
Defensive patterns

Strategy: validation

Validate before calling

// Never write to State outside the framework; if you must, validate.
func stateHealthy(app *fiber.App) error {
    for k, s := range app.State().Services() {
        if s == nil { return fmt.Errorf("nil service in state at %q", k) }
    }
    return nil
}

Prevention

When it happens

Trigger: Something wrote a nil into the State's service map after Start completed — e.g., a custom addon or test harness calling an unexported setter, or a race on shutdown. Under the normal Listen/Shutdown flow this is unreachable because setService only runs on successful Start.

Common situations: Test code that manipulates app.state directly; a fork that adds custom State mutation; memory corruption. Practically a defensive guard that should never fire in production.

Related errors


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

Appendix: 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 a105acad6c)