I lost an hour today to an error value that was plainly nil and just as plainly refused to compare equal to nil.

The reduced version looked like this:

type problem struct{}

func (*problem) Error() string { return "problem" }

func check() error {
	var p *problem
	return p
}

fmt.Println(check() == nil) // false

My first theory involved compiler spite. The real explanation is less personal: an interface value contains a dynamic type and a dynamic value. check returns an interface containing *problem and a nil pointer. The pointer is nil, but the interface’s type word is not, so the interface itself is not nil.

Printing %#v made the situation clearer:

(*main.problem)(nil)

The fix was not reflection or a clever nil helper. It was to return a literal nil when there is no error:

func check() error {
	var p *problem
	if p == nil {
		return nil
	}
	return p
}

This matters most with error, because callers naturally write if err != nil. I now keep concrete pointer errors inside the function and only convert them to error on an actual failure. Interfaces are two-word descriptions, not magic boxes. Remembering that is cheaper than another hour of accusing the compiler.