go-delve/delve · error · errMapBucketsNotStruct
malformed map type: buckets, oldbuckets or overflow field no
Error message
malformed map type: buckets, oldbuckets or overflow field not a struct
What it means
Delve's classic (pre-swiss-table) map iterator reads the runtime hmap/bucket structs directly, assuming each map internal type has well-formed fields. errMapBucketsNotStruct is returned by mapIterator and nextBucket when the 'buckets', 'oldbuckets' or 'overflow' field of the map's bucket struct is not a struct type, which means the loaded DWARF type information does not match the Go runtime layout Delve expects.
Source
Thrown at pkg/proc/mapiter.go:128
keyTypeIsPtr, elemTypeIsPtr bool
tophashes *Variable
keys *Variable
values *Variable
overflow *Variable
maxNumBuckets uint64 // maximum number of buckets to scan
idx int64
hashTophashEmptyOne uint64 // Go 1.12 and later has two sentinel tophash values for an empty cell, this is the second one (the first one hashTophashEmptyZero, the same as Go 1.11 and earlier)
hashMinTopHash uint64 // minimum value of tophash for a cell that isn't either evacuated or empty
}
var (
errMapBucketContentsNotArray = errors.New("malformed map type: keys, values or tophash of a bucket is not an array")
errMapBucketContentsInconsistentLen = errors.New("malformed map type: inconsistent array length in bucket")
errMapBucketsNotStruct = errors.New("malformed map type: buckets, oldbuckets or overflow field not a struct")
)
func (it *mapIteratorClassic) nextBucket() bool {
if it.overflow != nil && it.overflow.Addr > 0 {
it.b = it.overflow
} else {
it.b = nil
if it.maxNumBuckets > 0 && it.bidx >= it.maxNumBuckets {
return false
}
for it.bidx < it.numbuckets {
it.b = it.buckets.clone()
it.b.Addr += uint64(it.buckets.DwarfType.Size()) * it.bidx
if it.oldbuckets.Addr <= 0 {
breakView on GitHub (pinned to a23773e6c3)
Solutions
- Upgrade Delve to the version matching the Go toolchain used to build the target binary
- Rebuild the target binary without flags that strip DWARF (remove -ldflags "-s -w" or -trimpath misuse)
- Check the Go version of the binary (go version <binary>) and the Delve version (dlv version) for compatibility
Example fix
// before go build -ldflags="-s -w" main.go dlv exec ./main // after go build -gcflags="all=-N -l" main.go dlv exec ./main
Defensive patterns
Strategy: validation
Validate before calling
// In a delve support script or issue report, verify toolchain alignment first: // $ go version <target-binary> // $ dlv version // Proceed only if the Go major.minor of the binary matches a Delve release known to support it.
Prevention
- Keep Delve updated to the release matching your Go toolchain
- Build debug targets with full DWARF (no -s -w)
- Pin one Go version per debug environment to avoid layout drift
When it happens
Trigger: Evaluating or iterating a map whose bucket type parsed from DWARF has a non-struct buckets/oldbuckets/overflow field — e.g. calling 'print m' or a range expression on a map when the target binary's runtime type layout differs from what Delve expects (Go version mismatch, stripped or corrupted DWARF).
Common situations: Debugging a binary built with a much newer/older Go version than the map layout the Delve version supports; binaries with cgo or custom linkers producing unusual DWARF; attaching to processes built with trimmed debug info.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to find function context
- unable to find locals: no debug information present in binar
- wrong real type for map
- malformed map type: keys, values or tophash of a bucket is n
- malformed map type: inconsistent array length in bucket
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/4d692685551249bc.
Report an issue: GitHub.