SigNoz/signoz · critical
ErrCodeServiceFailed
ErrCodeServiceFailed
Error message
service %q failed before becoming healthy
What it means
Thrown by the service registry's AwaitHealthy when a service's Start() returned an error (startErr) before the healthy signal fired. It distinguishes a startup failure from a silent termination (which gets the 'terminated' variant), wrapping the original start error with ErrCodeServiceFailed.
Source
Thrown at pkg/factory/registry.go:184
}
}
return errors.Join(errs...)
}
// AwaitHealthy blocks until all services reach the RUNNING state or any service fails.
func (registry *Registry) AwaitHealthy(ctx context.Context) error {
for _, ss := range registry.services {
select {
case <-ctx.Done():
return ctx.Err()
case <-ss.healthyC:
case <-ss.startReturnedC:
ss.mu.RLock()
err := ss.startErr
ss.mu.RUnlock()
if err != nil {
return errors.Wrapf(err, errors.TypeInternal, ErrCodeServiceFailed, "service %q failed before becoming healthy", ss.service.Name())
}
return errors.Newf(errors.TypeInternal, ErrCodeServiceFailed, "service %q terminated before becoming healthy", ss.service.Name())
}
}
return nil
}
// ServicesByState returns a snapshot of the current state of all services.
func (registry *Registry) ServicesByState() map[State][]Name {
result := make(map[State][]Name)
for _, ss := range registry.services {
state := ss.getState()
result[state] = append(result[state], ss.service.Name())
}
return result
}
// IsHealthy returns true if all services are in the RUNNING state.View on GitHub (pinned to 5069bf80b0)
Solutions
- Read the wrapped startErr — it contains the actual startup failure; fix that first
- Check for port conflicts and required dependency availability before starting the service
- Use DependsOn/dependency ordering so prerequisites become healthy first
- Add startup retries/backoff for dependency connection failures at boot
Example fix
// before
if err := ss.AwaitHealthy(ctx); err != nil { panic(err) }
// after
if err := ss.AwaitHealthy(ctx); err != nil {
if errors.Is(err, registry.ErrCodeServiceFailed) {
log.Errorw("service failed to start", "service", name, "startErr", errors.Unwrap(err))
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: ensure dependencies are reachable before Start()
if err := db.Ping(); err != nil { return err } Try / catch
if err := ss.AwaitHealthy(ctx); err != nil {
return fmt.Errorf("bootstrap failed: %w", err) // wrapped startErr has the cause
} Prevention
- Always inspect the wrapped start error, not just the wrapper
- Bind ports only after checking availability
- Order service startup with DependsOn so dependencies are healthy first
When it happens
Trigger: Calling AwaitHealthy(ctx) on a registered service whose Start() blocked, then returned an error — e.g. a HTTP server failing to bind its port, a worker failing to connect to its broker, or a migrator failing before signaling healthy.
Common situations: Port already in use (EADDRINUSE) for the service's listener; required dependency (DB, Kafka) unavailable at boot; invalid service configuration causing immediate start failure; startup ordering issues where a dependent service starts before its dependency is healthy.
Related errors
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/afcad7b19593209c.
Report an issue: GitHub.