go-delve/delve · warning
unreadable tophash: %v
Error message
unreadable tophash: %v
What it means
While iterating a Go map during variable evaluation, the iterator reads each bucket's tophash byte. If that memory cannot be read (asUint fails, typically because the backing memory is unreadable), the resulting Variable is marked Unreadable with this error instead of continuing the iteration.
Source
Thrown at pkg/proc/mapiter.go:259
return false
}
return true
}
func (it *mapIteratorClassic) next() bool {
for {
if it.b == nil || it.idx >= it.tophashes.Len {
r := it.nextBucket()
if !r {
return false
}
it.idx = 0
}
tophash, _ := it.tophashes.sliceAccess(int(it.idx))
h, err := tophash.asUint()
if err != nil {
it.v.Unreadable = fmt.Errorf("unreadable tophash: %v", err)
return false
}
it.idx++
if h != hashTophashEmptyZero && h != it.hashTophashEmptyOne {
return true
}
}
}
func (it *mapIteratorClassic) key() *Variable {
k, _ := it.keys.sliceAccess(int(it.idx - 1))
if k.Kind == reflect.Ptr && !it.keyTypeIsPtr {
k = k.maybeDereference()
}
return k
}
func (it *mapIteratorClassic) value() *Variable {View on GitHub (pinned to a23773e6c3)
Solutions
- Re-read/re-evaluate the map variable at the current program stop instead of using a cached Variable
- Verify the target process memory is intact (check for heap corruption) and the core file is complete
- Check delve/Go version compatibility: map internals differ between Go versions and old delve builds misread new runtimes
Example fix
// before
v, _ := debugger.FindVariable(...)
iterate(v) // uses stale v after map was modified
// after
v, err := debugger.FindVariable(...) // re-evaluate at current stop
if err != nil { return err }
if v.Unreadable != nil { return v.Unreadable }
iterate(v) Defensive patterns
Strategy: fallback
Validate before calling
if v.Unreadable != nil {
return fmt.Errorf("map not readable: %v", v.Unreadable)
} Type guard
func isReadable(v *proc.Variable) bool {
return v.Unreadable == nil
} Try / catch
ok := iterateMap(it)
if !ok && it.v.Unreadable != nil {
if strings.Contains(it.v.Unreadable.Error(), "unreadable tophash") {
// re-evaluate the map at the current stop point
return reEvaluateAndIterate(mapExpr)
}
return it.v.Unreadable
} Prevention
- Re-evaluate map variables at each stop instead of caching them
- Match delve and Go runtime versions
- Check core dump completeness before map inspection
When it happens
Trigger: Evaluating/printing a map variable whose bucket tophash bytes live in memory delve cannot read (stale pointers, freed/corrupted map memory, reading a map from a core dump with missing pages).
Common situations: Inspecting a map after the underlying allocation was moved or freed (e.g. stale Variable captured before a map grew), debugging corrupted heap state, or reading maps from truncated core files.
Related errors
- wrong real type for map
- malformed map type
- could not load one of the tables
- bad swiss map, groups pointer is nil
- error accessing swiss map in table %d, group %d, slot %d
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/a80ee7748513bd5f.
Report an issue: GitHub.