crowdsecurity/crowdsec · warning
while waiting on httpServerTomb: %w
Error message
while waiting on httpServerTomb: %w
What it means
APIServer.Shutdown wraps an error returned by httpServerTomb.Wait() — the serving goroutine reported an error while being killed during shutdown. Normally Wait returns nil on graceful kill; a non-nil value means the server died abnormally.
Source
Thrown at pkg/apiserver/apiserver.go:501
if s.httpServer != nil {
if err := s.httpServer.Shutdown(ctx); err != nil {
return err
}
}
// close io.writer logger given to gin
if pipe, ok := gin.DefaultErrorWriter.(*io.PipeWriter); ok {
pipe.Close()
}
if pipe, ok := gin.DefaultWriter.(*io.PipeWriter); ok {
pipe.Close()
}
s.httpServerTomb.Kill(nil)
if err := s.httpServerTomb.Wait(); err != nil {
return fmt.Errorf("while waiting on httpServerTomb: %w", err)
}
return nil
}
func (s *APIServer) AttachPluginBroker(broker *csplugin.PluginBroker) {
s.controller.PluginChannel = broker.PluginChannel
}
func hasPlugins(profiles []*csconfig.ProfileCfg) bool {
for _, profile := range profiles {
if len(profile.Notifications) != 0 {
return true
}
}
return false
}View on GitHub (pinned to 909b515798)
Solutions
- Log the wrapped cause; it usually mirrors the listen failure (604) or http.Server.Serve error.
- If the process is exiting anyway, this is often benign — the original cause matters more.
- Ensure only one Shutdown/Run lifecycle per APIServer instance.
- Check for nil/failed listeners earlier in the shutdown sequence (e.g. pipe.Close errors).
Defensive patterns
Strategy: try-catch
Try / catch
if err := apiServer.Shutdown(); err != nil {
log.Warnf("LAPI shutdown reported: %v", err) // usually benign at exit
} Prevention
- Always call Run before Shutdown; never shut down twice.
- Log the wrapped cause to catch real listener failures early.
- Graceful-signal handling: SIGTERM -> Shutdown once.
- Treat non-nil Wait errors as symptoms of earlier failures, not root causes.
When it happens
Trigger: Shutdown called (process stopping, SIGTERM/SIGINT) and listenAndServeLAPI had already failed or returned an error during the kill sequence.
Common situations: Shutdown after a listener failure; tomb race where the goroutine errored concurrently with shutdown; bugs in plugin/connection close paths earlier in Shutdown.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- local API server stopped with error: %w
- appsec datasource requires a hub. this is a bug, please repo
- appsec datasource requires a lapi client configuration. this
- missing lapi client credentials
- kubernetes client is not initialized
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/002337e222bf59fb.
Report an issue: GitHub.