Nil Interface vs Nil Concrete Type
unexpected: err != nil is true even though the underlying value is nilQuick Answer
An interface is nil only when both its type and value are nil. Wrapping a nil pointer in an interface creates a non-nil interface. Return nil directly instead of a typed nil pointer.
Why This Happens
Go interfaces have two components: a type descriptor and a value. An interface is nil only when both are nil. If you return a nil pointer of a concrete type, the interface has a non-nil type descriptor, so it is not equal to nil. This is one of the most confusing aspects of Go.
The Problem
type MyError struct {
Message string
}
func (e *MyError) Error() string { return e.Message }
func validate() error {
var err *MyError = nil
return err // returns non-nil interface!
}
func main() {
if err := validate(); err != nil {
fmt.Println("got error:", err) // this executes!
}
}The Fix
func validate() error {
// return nil directly, not a typed nil pointer
return nil
}
func main() {
if err := validate(); err != nil {
fmt.Println("got error:", err)
}
}Step-by-Step Fix
- 1
Identify the typed nil return
Find functions returning an interface type where a nil pointer of a concrete type is returned.
- 2
Return nil directly
Replace return nilPointer with return nil to ensure the interface itself is nil.
- 3
Use reflect for debugging
Use reflect.ValueOf(err).IsNil() if you need to check if the underlying value is nil.
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