Matched signals
- WARNING: DATA RACE
- DATA RACE
- Previous read at
- Previous write at
- Read at 0x
- Write at 0x
- Goroutine.*running
- PASS (race)
Go race detector found a data race
What this failure means
The Go race detector identified a data race: two goroutines accessed the same memory location concurrently, with at least one performing a write, without any synchronization between them.
Symptoms
Faultline looks for one or more of these log fragments:
WARNING: DATA RACE
DATA RACE
Previous read at
Previous write at
Read at 0x
Write at 0x
Goroutine.*running
PASS (race)
Diagnosis
The Go race detector identified a data race: two goroutines accessed the same memory location concurrently, with at least one performing a write, without any synchronization between them.
Fix steps
- Read the full race report — it shows both goroutine stacks and the file/line for each conflicting access.
- Protect the shared variable with
sync.Mutexorsync.RWMutex, or use an atomic operation (sync/atomic) for simple counters. - Replace concurrent map access with
sync.Mapor add async.RWMutexaround reads and writes. - For loop-variable captures: copy the variable into a local before launching the goroutine:
v := v. - Run locally to reproduce:
go test -race ./...orgo test -race -count=5 ./...for intermittent races.
Validation
- Re-run the local reproduction command after the fix.
- go test -race ./…
- go test -race -count=10 ./path/to/package
Why it matters
Go’s race detector instruments every memory access at compile time (go test -race or go build -race). When it detects unsynchronized concurrent access, it prints the goroutine stacks for both the current and the previous conflicting access and exits with a non-zero status. Common causes: shared variable modified in a goroutine without a mutex, map written from multiple goroutines, or a closure capturing a loop variable that races with goroutines launched inside the loop.
Prevention
- Add
go test -race ./...as a required CI check on every PR. - Use
go vetandstaticcheckalongside the race detector to catch common sharing patterns before tests are written. - Prefer channel-based state sharing over shared memory for new concurrency code to reduce the likelihood of races by design.
Try it locally
go test -race ./...
go test -race -count=10 ./path/to/package
How Faultline detects it
Use faultline explain go-data-race to see the full playbook.
faultline analyze build.log
faultline explain go-data-race
Generated from playbooks/bundled/log/test/go-data-race.yaml. Do not edit directly.