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
- Increase the startup context deadline via ServicesStartupContextProvider.
- 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.
- Ensure infrastructure (DB, cache, message broker) is reachable with low latency from the process.
- 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
- Give each service a per-Start timeout below the global startup budget.
- Defer heavy warmup out of Start into a background goroutine.
- Verify dependency reachability before Listen.
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
- context canceled while starting service
- service terminate
- fiber: service at index
- fiber: service at index
- timeout or cancel
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)