#4665·crowdsec

Panic on shutdown when docker acquisition active: invalid memory address in tracker.Get (checkContainers)

Author: realAbitbolCreated Sep 7, 2026Updated Sep 7, 2026
Labelskind/bugneeds/triage

Bug description

CrowdSec (container, v1.8.1) crashes with exit code 1 every time it receives SIGTERM while a source: docker acquisition is active: instead of a clean shutdown it panics with invalid memory address or nil pointer dereference inside the docker acquisition module, ~0.5 s after SIGTERM is received.

Observed 4/4 times in 18 h on a Docker homelab (4 SIGTERM events → 4 panics → exit 1). Because the container runs with restart: unless-stopped, each shutdown looks like a crash loop to operators, though the process runs fine for hours in between.

Expected behavior

docker stop crowdsec (or any SIGTERM) should shut down cleanly with exit code 0, like any other stop of the container.

Actual behavior

time="2026-09-07T22:00:15Z" level=warning msg="SIGTERM received, shutting down"
time="2026-09-07T22:00:15Z" level=info msg="killing tail for container miniflux" module=acquisition.docker type=docker
time="2026-09-07T22:00:16Z" level=error msg="crowdsec - goroutine crashed: runtime error: invalid memory address or nil pointer dereference"
time="2026-09-07T22:00:16Z" level=fatal msg="crowdsec stopped unexpectedly."

Full panic stack (goroutine 146):

sync/atomic.(*Int32).Add(...)
	sync/atomic/type.go:94
sync.(*RWMutex).RLock(...)
	sync/rwmutex.go:72
github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/docker/tracker.(*Tracker[...]).Get(...)
	github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/docker/tracker/tracker.go:46 +0x22
github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/docker.(*Source).checkContainers(...)
	github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/docker/run.go:327 +0x4f6
github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/docker.(*Source).Watch(...)
	github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/docker/run.go:454 +0x653
github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/docker.(*Source).StreamingAcquisition(...)
	github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/docker/run.go:509 +0x23f
github.com/crowdsecurity/crowdsec/pkg/acquisition.acquireSource(...)
	github.com/crowdsecurity/crowdsec/pkg/acquisition/acquisition.go:609 +0x112
github.com/crowdsecurity/crowdsec/pkg/acquisition.StartAcquisition.func1()
	github.com/crowdsecurity/crowdsec/pkg/acquisition/acquisition.go:660 +0x470

Steps to reproduce

  1. Run crowdsecurity/crowdsec:latest (v1.8.1) in Docker with a docker acquisition datasource, e.g.:
    yaml
    source: docker
    docker_host: tcp://docker-socket-proxy:2375
    container_name: [miniflux]
    labels:
      type: miniflux
      program: miniflux
  2. Let it start and record logs ("Starting docker acquisition", "Starting tail").
  3. Send SIGTERM (docker stop crowdsec or any compose fleet recreate that stops the container).
  4. Observe: panic + level=fatal + exit code 1, every time.

Root cause analysis

The goroutine Watch (run.go:454) calls checkContainers (run.go:327), which does d.runningContainerState.Get(container.ID)Tracker.Get (tracker.go:46) → RLock. During shutdown the acquisition source / tracker is torn down while this goroutine is still executing, so RLock dereferences freed/invalid state → nil pointer panic. This is a shutdown race in the docker acquisition module.

Additional observations

  1. Present on master too: pkg/acquisition/modules/docker/tracker/tracker.go and pkg/acquisition/modules/docker/run.go are byte-identical between tag v1.8.1 and master (checked 2026-09-08). No fix upstream yet.
  2. Stacktrace is silently lost in the official image: /var/lib/crowdsec/data/trace is a symlink to /staging/ inside the image, so the trace write fails with unable to write stacktrace: open /var/lib/crowdsec/data/trace/.... This makes the crash look like a silent termination. Full traces are only recoverable from the container logs (escaped \n).

Environment

  • CrowdSec: v1.8.1-909b5157 (alphaga, BuildDate 2026-09-03, Go 1.26.8, Platform: docker)
  • Image: crowdsecurity/crowdsec:latest (pulled 2026-09-04)
  • Host: CachyOS Linux, Docker 29.7.2, containerd-snapshotter enabled
  • Container user: 1031:972 (non-root)
  • Acquisition: source: docker (via tecnativa/docker-socket-proxy, CONTAINERS=1) + several source: file datasources