panic: runtime error: index out of range [N] with length M

Quick answer

You indexed a slice/array out of bounds. The message is precise: [N] is the index you used, M is the length, so valid indexes are 0M-1. Fix it with a length check (if i < len(s)), a correct loop bound (i < len(s), not <=), or append instead of index-assignment on a zero-length slice.

The exact error string

s := []int{10, 20, 30}
fmt.Println(s[3])
// panic: runtime error: index out of range [3] with length 3

goroutine 1 [running]:
main.main()
        /app/main.go:7 +0x1d

How to read it

The two numbers are the whole diagnosis: [3] is the index you asked for, with length 3 is the slice's length — and the last valid index is always length − 1 (here, 2). So you went one past the end. The first main.* stack frame names the file:line; the slice indexed there is the culprit.

Cause 1: off-by-one loop

for i := 0; i <= len(s); i++ {   // ❌ <= goes one past the end
    fmt.Println(s[i])
}

for i := 0; i < len(s); i++ {    // ✅ last index is len(s)-1
    fmt.Println(s[i])
}
for i, v := range s {            // ✅ best — range can't overflow
    fmt.Println(i, v)
}

Cause 2: empty slice — [0] with length 0

first := results[0]              // ❌ panics if results is empty

if len(results) > 0 {           // ✅ guard
    first := results[0]
}

Cause 3: index-assign on a zero-length slice

make([]T, 0, cap) has length 0 even with capacity reserved — you must append, not index-assign:

s := make([]int, 0, 10)         // len 0, cap 10
s[0] = 1                        // ❌ index out of range [0] with length 0
s = append(s, 1)               // ✅ grows the slice

s := make([]int, 10)            // ✅ or make with a real length, then index
s[0] = 1

Cause 4: trusting external/JSON data length

Indexing fixed positions of a parsed payload (parts[1], row[2]) panics when the input is shorter than you assumed — a common bug with split strings, CSV rows, or JSON arrays from an API:

parts := strings.Split(line, ",")
name := parts[1]                // ❌ panics if the line had no comma

if len(parts) >= 2 {           // ✅ validate shape before indexing
    name := parts[1]
}

Common variants of this panic

MessageCauseFix
index out of range [N] with length Mindex ≥ lengthcheck i < len(s)
index out of range [0] with length 0empty sliceif len(s) > 0
panic in a for loop<= off-by-one< len(s) or range
panic on s[0]=xzero-length sliceappend or make([]T, n)
slice bounds out of range [a:b]bad slice expressionvalidate a, b vs len

Debugging checklist

Frequently Asked Questions

What does '[N] with length M' tell me?

N is the index you tried to access and M is the slice's length, so valid indexes are 0 to M-1. 'index out of range [3] with length 3' means you used index 3 on a 3-element slice (valid: 0,1,2). The numbers tell you exactly how far out of bounds you went.

Why does index out of range [0] with length 0 happen?

The slice is empty, so even index 0 is invalid. This is common when you access s[0] without checking, or read a result that came back empty. Guard with if len(s) > 0 before indexing, or handle the empty case explicitly.

How do I fix an off-by-one loop?

Use i < len(s), not i <= len(s) — the last valid index is len(s)-1. Better, range over the slice (for i, v := range s) which never goes out of bounds. Off-by-one in the loop condition is the most common cause of this panic.

Why does s[i] = x panic but append doesn't?

Index assignment requires the index to already exist; a make([]T, 0, cap) slice has length 0, so s[0]=x panics even though capacity is reserved. Use append(s, x) to grow the slice, or make([]T, n) with a real length if you intend to index by position.

Is this the same as 'slice bounds out of range'?

Related but distinct. 'index out of range' is a single bad index (s[i]); 'slice bounds out of range' comes from a bad slice expression (s[a:b] where a or b is invalid). Both are fixed by validating against len(s) before the operation.

How do I find where it panicked?

The first main.* frame in the goroutine stack names the file and line. Open it; the slice/array indexed on that line is the one out of bounds, and the [N] with length M values tell you the index and the actual length to reconcile.

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: nil pointer dereference Go: deadlock
About the author

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