crowdsecurity/crowdsec · critical
docker events connection failed: %w
Error message
docker events connection failed: %w
What it means
trySubscribeEvents calls d.Client.Events(ctx, opts) and checks the error channel non-blockingly for an immediate failure. If the docker daemon/socket is unreachable or the Events stream is rejected right away, the error is wrapped as "docker events connection failed". It signals the initial subscription to the docker event stream failed, not a mid-stream error.
Source
Thrown at pkg/acquisition/modules/docker/run.go:370
func (d *Source) trySubscribeEvents(ctx context.Context) (*subscription, error) {
filters := client.Filters{
"type": {
"container": true,
"service": d.isSwarmManager,
},
}
opts := client.EventsListOptions{
Filters: filters,
}
result := d.Client.Events(ctx, opts)
// Is there an immediate error (proxy/daemon unavailable) ?
select {
case err := <-result.Err:
if err != nil {
return nil, fmt.Errorf("docker events connection failed: %w", err)
}
default:
}
return &subscription{events: result.Messages, errs: result.Err}, nil
}
// subscribeEvents will loop until it can successfully call d.Client.Events()
// without immediately receiving an error. It applies exponential backoff on failures.
// Returns the new (eventsChan, errChan) pair or an error if context/tomb is done.
func (d *Source) subscribeEvents(ctx context.Context) (*subscription, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-d.t.Dying():
return nil, errors.New("connection aborted, shutting down docker watcher")
default:
}View on GitHub (pinned to 909b515798)
Solutions
- Check the daemon is reachable: `docker events --since 1s` on the same host/socket; fix DOCKER_HOST or the socket path in the docker datasource config.
- Fix permissions: add the crowdsec user to the docker group or adjust socket ACLs.
- If behind docker-socket-proxy, whitelist the /events (and containers) endpoints.
- Restart crowdsec once the daemon is up — the source retries subscription on the next manager loop.
Example fix
// before (acquis.yaml) source: docker // no docker_host, daemon not reachable // after — point at a working daemon/socket source: docker docker_host: unix:///var/run/docker.sock
Defensive patterns
Strategy: retry
Validate before calling
// Go, before starting the source
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if _, err := cli.Ping(ctx); err != nil {
return fmt.Errorf("docker daemon unreachable: %w", err)
} Try / catch
sub, err := trySubscribeEvents(ctx)
if err != nil && strings.Contains(err.Error(), "docker events connection failed") {
// exponential backoff, resubscribe once daemon is back
time.Sleep(backoff.Next())
goto retry
} Prevention
- Health-check the docker socket (client.Ping) at startup and in readiness probes.
- Mount /var/run/docker.sock when crowdsec runs in a container.
- Whitelist /events and /containers in docker-socket-proxy configs.
- Monitor daemon uptime; treat docker restarts as expected source restarts.
When it happens
Trigger: Calling the docker datasource startup (live mode, container discovery via events) when the docker daemon is down, the docker socket path is wrong, the user lacks permission on /var/run/docker.sock, or a docker-socket-proxy rejects the /events endpoint.
Common situations: CrowdSec started in a container without mounting /var/run/docker.sock; DOCKER_HOST pointing to a dead daemon; socket-proxy config missing GET /events in the allowed API; docker restarted while the source subscribes at boot.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- error connecting to websocket
- failed to get docker info: %w
- no crowdsec.enable key
- crowdsec.enable not a string
- crowdsec.enable not true
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/25571dbdb2aef8e3.
Report an issue: GitHub.