gofiber/fiber · error

service start

Error message

service %s start: %w

What it means

Returned by startServices() when srv.Start(ctx) itself returns an error that wraps context.Canceled or context.DeadlineExceeded (errors.Is matches). Unlike non-context errors which are collected and joined, a context error from Start causes an immediate return so the caller sees cancellation cleanly.

Solutions

  1. Increase the startup context deadline via ServicesStartupContextProvider.
  2. Make the service's Start() use a per-service timeout shorter than the global one so it fails before the global deadline if it cannot connect.
  3. Ensure infrastructure (DB, cache, message broker) is reachable with low latency from the process.
  4. Defer heavy work (migration, warmup) to a background goroutine outside Start.

Example fix

// before — Start blocks indefinitely on the global context
func (s *DBSvc) Start(ctx context.Context) error {
    db, err := sql.Open("postgres", s.dsn) // no per-call timeout
    return err
}
// global deadline expires -> service db start: context deadline exceeded

// after — per-service connect timeout
func (s *DBSvc) Start(ctx context.Context) error {
    cctx, cancel := context.WithTimeout(ctx, 5*time.Second)
    defer cancel()
    db, err := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(s.dsn)))
    if err != nil { return err }
    return db.PingContext(cctx)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Per-service connect timeout smaller than the global startup budget.
func startWithTimeout(s fiber.Service, parent context.Context, d time.Duration) error {
    ctx, cancel := context.WithTimeout(parent, d)
    defer cancel()
    return s.Start(ctx)
}

Try / catch

if err := app.Listen(":3000"); err != nil {
    if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
        log.Printf("startup canceled: %v", err)
    }
    log.Fatal(err)
}

Prevention

When it happens

Trigger: A service's Start() respects the passed ctx and returns ctx.Err() (Canceled/DeadlineExceeded) when the startup context expires mid-start. The service correctly propagates cancellation and Fiber surfaces it without attempting remaining services.

Common situations: Service Start() blocks on a network/DB connect with the startup context; the deadline expires during that connect; SIGINT cancels the startup context; a dependency service is slow and pushes a later service past its own deadline.

Related errors


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

Appendix: source

Thrown at services.go:105

	for idx, srv := range app.configured.Services {
		if srv == nil {
			return fmt.Errorf("fiber: service at index %d is nil", idx)
		}
		if err := ctx.Err(); err != nil {
			// Context is canceled, return an error the soonest possible, so that
			// the user can see the context cancellation error and act on it.
			return fmt.Errorf("context canceled while starting service %s: %w", srv.String(), err)
		}

		err := srv.Start(ctx)
		if err == nil {
			// mark the service as started
			app.state.setService(srv)
			continue
		}

		if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
			return fmt.Errorf("service %s start: %w", srv.String(), err)
		}

		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 {

View on GitHub (pinned to a105acad6c)