Quick answer
You used a nil pointer, nil map, or nil interface. The [signal SIGSEGV ... addr=0x0] line confirms it — 0x0 is the nil address — and the top stack frame names the exact line. Fix it with a nil check before the dereference, proper initialization (make() for maps, &T{} for pointers), and by checking err before using a returned value.
The exact error string
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x...]
goroutine 1 [running]:
main.(*User).Greet(...)
/app/main.go:14 +0x18 <-- the line that dereferenced nil
main.main()
/app/main.go:9 +0x25
How to read the panic (find the nil)
Two clues pinpoint it: addr=0x0 means the address was nil, and the first main.* frame in the goroutine trace is your line. Open that file:line — the value you dereferenced there (p.Field, m[k] = v, x.Method()) is the nil one. A quick fmt.Printf("%+v\n", suspect) just above that line confirms which variable.
Cause 1: dereferencing a nil pointer
type User struct{ Name string }
var u *User // nil pointer
fmt.Println(u.Name) // ❌ panic: nil pointer dereference
if u != nil { // ✅ guard
fmt.Println(u.Name)
}
u = &User{Name: "Ada"} // ✅ or initialize it
Many nil-pointer bugs are just a forgotten initialization. A constructor function that always returns a ready-to-use value is the idiomatic guard — callers can't accidentally get a nil (or a struct with nil fields) back:
type Service struct{ cache map[string]int }
func NewService() *Service { // ✅ always returns a usable *Service
return &Service{cache: make(map[string]int)} // fields initialized too
}
svc := NewService()
svc.cache["hits"]++ // no nil pointer, no nil map
Cause 2: writing to a nil map
A note on the message: writing to a nil map panics with assignment to entry in nil map — a separate runtime panic with a different string from invalid memory address or nil pointer dereference. Developers hit them together (both come from an uninitialized value), so this page covers both, but they are distinct messages. A declared map is nil until you make it; reading a nil map is fine (zero value), but writing panics:
var m map[string]int // nil map
m["a"] = 1 // ❌ panic: assignment to entry in nil map
m = make(map[string]int) // ✅ initialize before writing
m["a"] = 1
Nil map vs nil slice vs nil pointer
These are easy to confuse but behave differently — the difference is Go's philosophy of useful zero values. A nil slice is far more forgiving than a nil map:
var s []int // nil slice
_ = len(s) // ✅ 0
_ = append(s, 1) // ✅ append works on a nil slice
for range s {} // ✅ zero iterations
// _ = s[0] // ❌ index out of range (it's empty), not a nil panic
var m map[string]int // nil map
_ = m["x"] // ✅ read returns the zero value
// m["x"] = 1 // ❌ assignment to entry in nil map
So var s []int is usually safe to use immediately, while var m map[string]int must be maked before you write to it. Quick reference for the zero value of each type:
| Type | Zero value | Usable as-is? |
|---|---|---|
| slice | nil | len, range, append ✓ · index ✗ (empty) |
| map | nil | read ✓ · write ✗ (panics) |
| pointer | nil | dereference ✗ (panics) |
| channel | nil | send/receive block forever |
Cause 3: using a result without checking err
When a function returns (T, error) and errors, T is usually its zero value (often a nil pointer). Using it dereferences nil:
resp, err := http.Get(url)
defer resp.Body.Close() // ❌ resp is nil when err != nil
resp, err := http.Get(url)
if err != nil { // ✅ check first
return err
}
defer resp.Body.Close()
Cause 4: the typed-nil interface trap
An interface that holds a nil pointer is not a nil interface, so a != nil check passes and a later method call panics:
func find() error {
var e *MyError = nil
return e // ❌ returns a non-nil interface wrapping a nil *MyError
}
if err := find(); err != nil { // true! then err.Error() may panic
log.Println(err.Error())
}
// ✅ return a literal nil when there's no error:
func find() error { return nil }
Common variants of this panic
| Message / situation | Cause | Fix |
|---|---|---|
nil pointer dereference | nil *T dereferenced | nil-check or initialize &T{} |
assignment to entry in nil map | writing to a nil map | make(map[K]V) first |
| panic right after a call | used result without checking err | if err != nil { return } |
err != nil but value is "nil" | typed nil in an interface | return literal nil |
| nil receiver method | method called on a nil pointer | guard the receiver / construct it |
Debugging checklist
- ✓
addr=0x0in the signal line confirms a nil dereference - ✓ The first
main.*stack frame names the exact file:line - ✓ Pointer nil? Guard with
if p != nilor initialize&T{} - ✓ Writing a map?
make(map[K]V)before assigning - ✓ After a
(T, error)call? Checkerrbefore usingT - ✓
!= nilpasses but it still panics? Suspect a typed-nil interface - ✓ Server handler?
recover()for resilience, but still fix the nil
Frequently Asked Questions
What does 'invalid memory address or nil pointer dereference' mean in Go?
Your program tried to read or write through a nil pointer (or a nil map, nil interface, or the pointer inside a nil-valued interface). The accompanying [signal SIGSEGV ... addr=0x0] confirms it: addr=0x0 is the nil address. The stack trace's top frame and line number point to the exact dereference.
How do I find which value is nil?
Read the first frame of the panic stack — it names the function and line. The expression being dereferenced there (p.Field, m[key]=..., obj.Method()) is the nil one. addr=0x0 confirms nil; print the suspect with %v / %+v just before that line to see which variable is nil.
Why does writing to a map panic?
A declared-but-not-initialized map is nil, and writing to a nil map panics (reading returns the zero value, which hides it). Initialize it with make(map[K]V) or a literal map[K]V{} before assigning keys. Note a nil slice is different: len, range, and append all work on it — only indexing past its (zero) length fails, and that's an index out of range panic, not a nil-map or nil-pointer one.
Why do I get a nil panic right after a function that returns an error?
You used the returned value without checking the error. When err != nil, the other return value is usually the zero value (often a nil pointer), so using it dereferences nil. Always check if err != nil and return/handle before touching the result.
What is a typed nil / nil interface gotcha?
An interface holding a nil pointer is not equal to a nil interface: var p *T = nil; var i interface{} = p makes i != nil even though the underlying pointer is nil. Calling a method that dereferences the receiver then panics. Return a literal nil (not a typed nil pointer) when you mean "no value".
Can I recover from a nil pointer panic?
You can recover() in a deferred function to stop the panic from crashing the process (common in server request handlers), but recover is for resilience, not a fix. The real fix is the nil check or initialization; treat a nil-pointer panic as a bug to eliminate, not catch.
More backend & language errors
Browse the full reference for Go, Node.js, Python, and database errors — exact message, cause, and fix.