---
title: "nil pointer dereference em Go"
url: "https://golang.com.br/erros/nil-pointer-dereference/"
markdown_url: "https://golang.com.br/erros/nil-pointer-dereference.MD"
description: "Resolva o panic 'nil pointer dereference' em Go. Entenda causas de ponteiro nulo, como prevenir e técnicas para debug de panics no runtime."
date: "2026-05-12"
author: "Golang Brasil"
---

# nil pointer dereference em Go

Resolva o panic 'nil pointer dereference' em Go. Entenda causas de ponteiro nulo, como prevenir e técnicas para debug de panics no runtime.


# nil pointer dereference em Go

O **"runtime error: invalid memory address or nil pointer dereference"** é um dos panics mais comuns em programas Go. Ele acontece quando você tenta acessar um campo, chamar um método ou desreferenciar um ponteiro que tem valor `nil` — ou seja, não aponta para nenhum endereço de memória válido.

Diferente de linguagens com exceções como Java (`NullPointerException`) ou C# (`NullReferenceException`), em Go esse erro causa um **panic** que, se não recuperado, derruba o programa inteiro.

---

## A Mensagem de Erro

```
goroutine 1 [running]:
main.main()
    /app/main.go:12 +0x1e
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x47f68e]
```

---

## Causas Comuns

### 1. Ponteiro Não Inicializado

Quando você declara um ponteiro sem inicializá-lo, ele é `nil` por padrão:

```go
package main

import "fmt"

type Usuario struct {
    Nome  string
    Email string
}

func main() {
    var u *Usuario // u é nil

    // PANIC: nil pointer dereference
    fmt.Println(u.Nome)
}
```

### 2. Retorno nil Não Verificado

Funções que retornam ponteiros podem retornar `nil` em caso de erro:

```go
package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("arquivo-inexistente.txt")
    // Se ignorar err, file pode ser nil!
    // PANIC ao tentar usar file
    fmt.Println(file.Name())
    _ = err
}
```

### 3. Map Não Inicializado com Structs

Maps retornam o zero value quando a chave não existe. Para ponteiros, isso é `nil`:

```go
package main

import "fmt"

type Config struct {
    Valor string
}

func main() {
    configs := map[string]*Config{
        "prod": {Valor: "producao"},
    }

    // "dev" não existe no map — retorna nil
    dev := configs["dev"]

    // PANIC: nil pointer dereference
    fmt.Println(dev.Valor)
}
```

### 4. Interface com Valor nil

Uma interface pode conter um ponteiro `nil`, o que gera confusão:

```go
package main

import "fmt"

type Logger interface {
    Log(msg string)
}

type FileLogger struct {
    Path string
}

func (f *FileLogger) Log(msg string) {
    fmt.Printf("[%s] %s\n", f.Path, msg)
}

func getLogger() Logger {
    var fl *FileLogger // nil
    return fl          // Interface não-nil contendo ponteiro nil!
}

func main() {
    logger := getLogger()

    // logger != nil (interface tem tipo, mas valor nil)
    if logger != nil {
        // PANIC: o valor dentro da interface é nil
        logger.Log("teste")
    }
}
```

### 5. Slice de Ponteiros

Quando você tem um slice de ponteiros e algum elemento é `nil`:

```go
package main

import "fmt"

type Pedido struct {
    ID    int
    Total float64
}

func main() {
    pedidos := []*Pedido{
        {ID: 1, Total: 99.90},
        nil, // Elemento nil!
        {ID: 3, Total: 45.00},
    }

    for _, p := range pedidos {
        // PANIC quando p é nil
        fmt.Printf("Pedido %d: R$ %.2f\n", p.ID, p.Total)
    }
}
```

---

## Como Resolver

### Solução 1: Sempre Verificar nil

A forma mais direta — verifique antes de usar:

```go
package main

import "fmt"

type Usuario struct {
    Nome string
}

func buscarUsuario(id int) *Usuario {
    if id == 1 {
        return &Usuario{Nome: "Alice"}
    }
    return nil
}

func main() {
    u := buscarUsuario(2)

    // Verifica nil antes de acessar
    if u != nil {
        fmt.Println(u.Nome)
    } else {
        fmt.Println("Usuário não encontrado")
    }
}
```

### Solução 2: Tratar Erros Antes de Usar o Resultado

Siga o padrão idiomático de [tratamento de erros em Go](/aprenda/golang-erros/):

```go
package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("config.json")
    if err != nil {
        fmt.Println("Erro:", err)
        return // Sai antes de usar file
    }
    defer file.Close()

    // Seguro: file não é nil aqui
    fmt.Println("Arquivo:", file.Name())
}
```

### Solução 3: Inicializar com Valor Padrão

Use construtores ou valores padrão para evitar ponteiros nil:

```go
package main

import "fmt"

type Config struct {
    Host string
    Port int
}

// Construtor que nunca retorna nil
func NewConfig() *Config {
    return &Config{
        Host: "localhost",
        Port: 8080,
    }
}

func main() {
    cfg := NewConfig() // Nunca nil
    fmt.Printf("%s:%d\n", cfg.Host, cfg.Port)
}
```

### Solução 4: Verificar Maps com ok

Use o idioma de dois valores para maps:

```go
package main

import "fmt"

type Config struct {
    Valor string
}

func main() {
    configs := map[string]*Config{
        "prod": {Valor: "producao"},
    }

    // Verifica se a chave existe
    if dev, ok := configs["dev"]; ok {
        fmt.Println(dev.Valor)
    } else {
        fmt.Println("Configuração 'dev' não encontrada")
    }
}
```

### Solução 5: Usar recover para Panics Inesperados

Em servidores HTTP e sistemas que não podem cair, use `recover`:

```go
package main

import "fmt"

func processarSeguro(dados interface{}) (resultado string, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("panic recuperado: %v", r)
        }
    }()

    // Código que pode causar panic
    m := dados.(map[string]string)
    return m["chave"], nil
}

func main() {
    resultado, err := processarSeguro(nil)
    if err != nil {
        fmt.Println("Erro:", err)
        return
    }
    fmt.Println(resultado)
}
```

---

## Técnicas de Debug

### Stack Trace

Quando um nil pointer dereference acontece, Go imprime o stack trace completo. Leia de baixo para cima para encontrar a causa:

```
goroutine 1 [running]:
main.processarPedido(0x0)           # <-- ponteiro 0x0 = nil!
    /app/handlers.go:45 +0x1e
main.main()
    /app/main.go:12 +0x3a
```

### Delve Debugger

Use o [Delve](https://github.com/go-delve/delve) para depurar interativamente:

```bash
# Instalar
go install github.com/go-delve/delve/cmd/dlv@latest

# Executar com debugger
dlv debug .
```

Consulte nosso guia de [profiling e performance](/tutoriais/go-performance-profiling/) para mais técnicas de debug.

---

## Dicas para Evitar Este Erro

1. **Prefira valores a ponteiros** — se a struct é pequena, passe por valor ao invés de ponteiro. Sem ponteiro, sem nil.

2. **Siga o padrão `if err != nil`** — nunca ignore o retorno de erro. Veja [tratamento de erros em Go](/aprenda/golang-erros/).

3. **Use construtores (New...)** — funções como `NewConfig()` garantem inicialização correta. Veja [clean architecture em Go](/tutoriais/go-clean-architecture/) para padrões de projeto.

4. **Inicialize maps com `make`** — `var m map[string]int` é nil. Use `m := make(map[string]int)`.

5. **Habilite `go vet` e linters** — [staticcheck](https://staticcheck.dev/) e [golangci-lint](/blog/melhores-ferramentas-go-2026/) detectam possíveis nil dereferences.

6. **Escreva testes** — [testes unitários](/aprenda/testes-go/) e [testes de tabela](/blog/testes-tabela-go-guia-table-driven-tests/) com casos nil previnem regressões.

Vale notar que linguagens como <a href="https://rustlang.com.br/blog/" target="_blank" rel="noopener noreferrer" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust</a> eliminam nil pointer dereferences em tempo de compilação usando `Option<T>`, e <a href="https://kotlin.dev.br/blog/" target="_blank" rel="noopener noreferrer" onclick="umami.track('portfolio-site-click', { destination: 'kotlin.dev.br' })">Kotlin</a> aborda o problema com null safety nativo no sistema de tipos.

---

## Erros Relacionados

- [deadlock — all goroutines are asleep](/erros/deadlock-goroutines/) — outro panic comum em runtime
- [race condition / data race](/erros/race-condition-data-race/) — acessos concorrentes podem causar nil inesperado
- [cannot use X as type Y](/erros/cannot-use-x-as-type-y/) — problemas de tipo com ponteiros vs valores
- [Concorrência em Go](/aprenda/concorrencia-go/) — goroutines e compartilhamento seguro de dados
