concurrent map writes
Go Programming Language
Severity: CriticalWhat it means
Go maps are not safe for concurrent use from multiple goroutines.
Two goroutines writing to the same map at the same time causes a fatal crash.
This is not a panic — it cannot be recovered.
The program exits immediately.
Affected Models
- Go 1.21
- Go 1.22
- Go 1.23
- Go 1.24
Common Causes
- Two or more goroutines writing to the same map simultaneously
- One goroutine reading and another writing to the same map at the same time
- Sharing a map through a closure between goroutines without synchronization
- Using a map as a shared cache without a mutex or lock
- Not realizing a library function runs its callback in a goroutine
How to Fix It
-
Add a sync.RWMutex to protect your map. Lock before writing, unlock after.
var mu sync.RWMutex — use mu.Lock() / mu.Unlock() for writes, mu.RLock() / mu.RUnlock() for reads.
-
Switch to sync.Map, which is built for concurrent access.
var m sync.Map — use m.Store(key, value) and m.Load(key).
No mutex needed. -
Use the race detector during development: go run -race main.go
This catches data races before they crash production.
Make it part of your test workflow. -
Isolate map ownership — let only one goroutine own and write to the map.
Pass updates through a channel to a single 'manager' goroutine.
This is the cleanest Go-idiomatic solution. -
Add go test -race to your CI pipeline to catch race conditions automatically.
Race conditions are non-deterministic.
Tests pass most of the time but fail randomly in production.
When to Call a Professional
If this error appears in a production service, stop and audit all shared state.
Data races can cause silent corruption — not just crashes.
Consider a code review focused on concurrency safety.
Frequently Asked Questions
Why can't I recover() from a concurrent map write?
Go's runtime deliberately makes this a fatal error, not a panic.
The design choice is intentional — a corrupted map is unrecoverable.
recover() only works for panics, not fatal errors.
Is sync.Map always better than a map with a mutex?
Not always. sync.Map is optimized for read-heavy workloads with infrequent writes.
For write-heavy workloads, a map with sync.RWMutex is often faster.
Benchmark both for your specific use case.
Does this error appear if two goroutines only read from the map?
No.
Concurrent reads from a map are safe in Go.
The crash only happens when at least one goroutine is writing.
Write and read at the same time is also unsafe.