Skip to content

How to Fix Go Slice Append Capacity and Underlying Array Errors

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about How to Fix Go Slice Append Capacity and Underlying Array Errors. We cover key concepts, practical examples, and best practices.

Go slice append surprises occur when appending to a slice that shares the same backing array with another slice. Appending past capacity creates a new array, leaving the original slice unaffected and producing unexpected aliasing.

Quick Fix

Wrong

original := []int{1, 2, 3, 4, 5}
sub := original[1:3] // sub = [2, 3], len=2, cap=4
sub = append(sub, 99)
fmt.Println("original:", original)
fmt.Println("sub:", sub)
original: [1 2 3 99 5]
sub: [2 3 99]

sub shares the backing array with original. Appending to sub overwrote original[3] because sub had spare capacity.

original := []int{1, 2, 3, 4, 5}
sub := make([]int, 2)
copy(sub, original[1:3])
sub = append(sub, 99)
fmt.Println("original:", original)
fmt.Println("sub:", sub)
original: [1 2 3 4 5]
sub: [2 3 99]

Using copy creates an independent backing array for sub.

Fix with full slice expression

original := []int{1, 2, 3, 4, 5}
sub := original[1:3:3] // len=2, cap=3
sub = append(sub, 99)  // forces allocation of new array
fmt.Println("original:", original)
fmt.Println("sub:", sub)

Fix by pre-allocating capacity

// Pre-allocate to avoid repeated allocations
data := make([]int, 0, 1000)
for i := 0; i < 1000; i++ {
    data = append(data, i)
}

Prevention

  • Use copy when taking subslices that may be appended to.
  • Use the full slice expression a[low:high:max] to limit capacity.
  • Pre-allocate slices with make([]T, 0, capacity) for known sizes.
  • Never assume that append on a subslice will not affect the parent.
  • Run go vet with -copylocks and check for slice aliasing.

DodaTech Tools

Doda Browser's Go memory profiler visualizes slice backing array sharing and reallocation events. DodaZIP archives heap profiles for analysis. Durga Antivirus Pro detects unintended slice aliasing in code.

Common Mistakes with slice append

  1. Non-exhaustive pattern matches that compile with warnings then crash at runtime
  2. Misunderstanding that String is [Char] with poor performance for large text operations
  3. Using foldl instead of foldl' causing stack overflow on large lists

These mistakes appear frequently in real-world GO code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

When does `append` create a new backing array?

When the slice's length would exceed its capacity after appending. If the slice has spare capacity, append reuses the existing backing array. The capacity grows by doubling (for small slices) or by 25% (for large slices).

How do I guarantee a subslice has its own backing array?

Use copy: sub := make([]T, n); copy(sub, original[low:high]). This creates a completely independent slice with no shared memory.

Can I force `append` to always allocate a new array?

Use the full slice expression with max capacity: sub := original[1:3:3] sets capacity equal to length, so any append forces allocation.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro