Skip to content
Latchkey

Go "DATA RACE" - Fix go test -race Detector Failures in CI

The race detector (go test -race) caught two goroutines accessing the same memory concurrently, at least one of them writing, with no synchronization. This is a real bug - data races are undefined behavior in Go.

What this error means

go test -race prints WARNING: DATA RACE with the conflicting read and write goroutine stacks, then fails the test. Without -race the same test may pass, which is why it surfaces only in a race-enabled CI run.

go test output
==================
WARNING: DATA RACE
Write at 0x00c0000b4010 by goroutine 8:
  github.com/yourorg/app.(*Counter).Inc()
      counter.go:14 +0x44

Previous read at 0x00c0000b4010 by goroutine 7:
  github.com/yourorg/app.(*Counter).Value()
      counter.go:18 +0x38
==================

Common causes

Unsynchronized shared state

Multiple goroutines read and write the same variable, map, or struct field without a mutex, channel, or atomic, so the accesses race.

Concurrent map access

Reading and writing a built-in map from different goroutines is a classic race the detector flags (and can also panic at runtime).

How to fix it

Add synchronization at the conflict point

Read the two stacks the detector prints - they name the exact lines. Protect that shared state.

counter.go
import "sync"

type Counter struct {
	mu sync.Mutex
	n  int
}

func (c *Counter) Inc()  { c.mu.Lock(); c.n++; c.mu.Unlock() }
func (c *Counter) Value() int { c.mu.Lock(); defer c.mu.Unlock(); return c.n }

Use atomics or channels where appropriate

  1. For simple counters/flags, use sync/atomic instead of a mutex.
  2. For ownership transfer, pass data over a channel rather than sharing it.
  3. For maps under concurrency, use sync.Map or guard with a mutex.

How to prevent it

  • Run go test -race in CI so races fail the build, not production.
  • Guard all shared mutable state with a mutex, atomic, or channel.
  • Treat a DATA RACE as a real bug - it is never safe to ignore.

Frequently asked questions

Can I just retry past a DATA RACE?
No. A data race is undefined behavior, not flake. It may pass on retry purely by timing, but the bug is still there and can corrupt data or crash in production. Fix the synchronization.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card