panic: runtime error: invalid memory address or nil pointer dereference

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:

TypeZero valueUsable as-is?
slicenillen, range, append ✓ · index ✗ (empty)
mapnilread ✓ · write ✗ (panics)
pointernildereference ✗ (panics)
channelnilsend/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 / situationCauseFix
nil pointer dereferencenil *T dereferencednil-check or initialize &T{}
assignment to entry in nil mapwriting to a nil mapmake(map[K]V) first
panic right after a callused result without checking errif err != nil { return }
err != nil but value is "nil"typed nil in an interfacereturn literal nil
nil receiver methodmethod called on a nil pointerguard the receiver / construct it

Debugging checklist

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.

All Error References Go: index out of range Go: cannot unmarshal JSON
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.