#22440·etcd

rafthttp: snapshotHandler panics on MsgSnap with missing Snapshot

Author: deb000-sourceCreated Sep 16, 2026Updated Sep 16, 2026
Labelstype/bug

Bug report criteria

What happened?

A validly encoded MsgSnap without the optional Snapshot field causes a nil dereference at rafthttp/http.go:272.

What did you expect to happen?

Return 400 Bad Request.

How can we reproduce it (as minimally and precisely as possible)?

Send a POST request to /raft/snapshot with normal valid peer headers and the following raw body:

00 00 00 00 00 00 00 02 08 07

The first 8 bytes are the message length (2). 08 07 encodes a protobuf Message with Type=MsgSnap, while field 9 (Snapshot) is absent.

The message decodes successfully, then snapshotHandler dereferences m.Snapshot.Metadata with m.Snapshot == nil and panics.

Anything else we need to know?

Message.Snapshot is *Snapshot, but the handler checks only m.GetType() before dereferencing m.Snapshot.Metadata.

In raft v3.5, Snapshot was a value field, so an omitted protobuf field decoded to the zero-value Snapshot. In v3.7, it is a pointer, so the same wire message leaves it nil, while snapshotHandler still dereferences it unconditionally.

Etcd version (please run commands below)

A standalone etcd binary was not used.

Reproduced against a locally modified source checkout based on etcd v3.7.1. The affected snapshotHandler code path matches upstream etcd v3.7.1.

Go: go1.26.5 linux/amd64 etcdctl was not involved.

Etcd configuration (command line flags or environment variables)

No response

Etcd debug information (please run commands below, feel free to obfuscate the IP address or FQDN in the output)

No response

Relevant log output

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

go.etcd.io/etcd/server/v3/etcdserver/api/rafthttp.(*snapshotHandler).ServeHTTP
    server/etcdserver/api/rafthttp/http.go:272