How private is private Trivia time! I recently ran into a -race error message that stumped me for a while, so I’ll retell it here in phases to see if you can catch it. The code The intent of the was a service abstraction that ran a goroutine in the background to send runtime stats to . A small example of the code follows: code Stastd You can be 100% sure that I never run Loop() for the same Stats struct. And you’re 100% sure I only make a single Stats{} struct in my program. Before reading forward, inspect the above code and see if you can find the condition I hit while using Stats. race A hint The race condition occurred on line 19 that looks like. p.prev = ms Does that help find the race condition? A second, bigger hint The code that created my service structure looked somewhat like the following. Private doesn’t mean undiscoverable When you try to print a structure in Go with the Sprint or Println family of operations it will check to see if it’s a Formatter or Stringer and usually use those methods, otherwise it will use reflection to invent a way to print the structure. You can inspect the conditions for when is uses Formatter or Stringer . inside print.go This particular code stumped me because I kept looking at Stats{} and thinking t_here’s no way that is a race. I keep_ . However, with Go, you can use reflection to inspect private variables. This inspection created the read operation that caused a race condition to trigger. This is very reasonable, especially since you can trigger a read of private variables even without reflection by taking the value of a structure prev private and never reference it s := Stats{}q := s // Will read stats to make a copy inside q Thankfully, we can’t use reflection to set a private variable. See for a description of when you can and cannot. Value.CanSet The moral of this little trivia is to remember that private variables can cause read -race errors, via copy and reflection, even if looking at the struct itself it appears safe.