Why This Happens
Go's net/http server handles each request in its own goroutine. If your handler reads or writes shared variables like an in-memory cache or counter, you must synchronize access. This is easily missed because the code looks sequential in each handler function.
The Problem
var visitCount int
func handler(w http.ResponseWriter, r *http.Request) {
visitCount++ // race condition
fmt.Fprintf(w, "Visits: %d", visitCount)
}The Fix
var visitCount int64
func handler(w http.ResponseWriter, r *http.Request) {
count := atomic.AddInt64(&visitCount, 1)
fmt.Fprintf(w, "Visits: %d", count)
}Step-by-Step Fix
- 1
Identify shared state
Find package-level or struct-level variables accessed by HTTP handlers without synchronization.
- 2
Choose a sync mechanism
Use sync/atomic for simple counters, sync.Mutex for complex state, or sync.Map for concurrent maps.
- 3
Test with -race flag
Run go test -race to verify no data races remain in your handlers.
Got the actual stack trace?
Paste it into our free AI explainer to get the cause and the fix for your specific case — no signup, nothing to install.
Explain my errorBugsly catches this automatically
Bugsly's AI analyzes this error pattern in real-time, explains what went wrong in plain English, and suggests the exact fix — before your users even report it.
Try Bugsly free