Ad Space — Top Banner

concurrent map writes

Go Programming Language

Severity: Critical

What Does This Error Mean?

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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.