go-delve/delve · error
len must be less than or equal to %d
Error message
len must be less than or equal to %d
What it means
ExamineMemory enforces a hard cap of ExamineMemoryLengthLimit (1<<16 = 65536) bytes per request and throws this error when arg.Length exceeds it. The limit protects the debugger and client from absurdly large single reads over the RPC channel.
Source
Thrown at service/rpc2/server.go:1012
}
// ExamineMemoryIn holds the arguments of ExamineMemory
type ExamineMemoryIn struct {
Address uint64
Length int
}
// ExaminedMemoryOut holds the return values of ExamineMemory
type ExaminedMemoryOut struct {
Mem []byte
IsLittleEndian bool
}
const ExamineMemoryLengthLimit = 1 << 16
func (s *RPCServer) ExamineMemory(arg ExamineMemoryIn, out *ExaminedMemoryOut) error {
if arg.Length > ExamineMemoryLengthLimit {
return fmt.Errorf("len must be less than or equal to %d", ExamineMemoryLengthLimit)
}
Mem, err := s.debugger.ExamineMemory(arg.Address, arg.Length)
if err != nil {
return err
}
out.Mem = Mem
out.IsLittleEndian = true //TODO: get byte order from debugger.target.BinInfo().Arch
return nil
}
type StopRecordingIn struct {
}
type StopRecordingOut struct {
}
View on GitHub (pinned to a23773e6c3)
Solutions
- Chunk the read: loop with Length <= 65536 and increment Address by the chunk size
- Clamp the request to min(desired, rpc2.ExamineMemoryLengthLimit) before calling
- For large dumps, read the region in pages and concatenate results client-side
- Check the constant at runtime (rpc2.ExamineMemoryLengthLimit) instead of hardcoding 65536 in case it changes
Example fix
// before
data, err := client.ExamineMemory(rpc2.ExamineMemoryIn{Address: addr, Length: 1 << 20}) // too large
// after
const chunk = 1 << 16
var data []byte
for off := uint64(0); off < 1<<20; off += chunk {
out, err := client.ExamineMemory(rpc2.ExamineMemoryIn{Address: addr + off, Length: chunk})
if err != nil {
return err
}
data = append(data, out.Mem...)
} Defensive patterns
Strategy: validation
Validate before calling
func clampLength(n uint32) uint32 {
if n > rpc2.ExamineMemoryLengthLimit {
return rpc2.ExamineMemoryLengthLimit
}
return n
}
// use: Length: clampLength(requested) Try / catch
out, err := client.ExamineMemory(rpc2.ExamineMemoryIn{Address: addr, Length: n})
if err != nil && strings.Contains(err.Error(), "len must be less than or equal to") {
return fmt.Errorf("request %d bytes exceeds %d-byte limit; chunk the read", n, rpc2.ExamineMemoryLengthLimit)
} Prevention
- Always chunk large memory dumps into <=64KiB reads
- Reference rpc2.ExamineMemoryLengthLimit instead of hardcoding the value
- Sanitize user-supplied dump sizes at the tool boundary
- Accumulate chunked reads into one buffer when a full region is needed
When it happens
Trigger: Calling RPCClient.ExamineMemory with ExamineMemoryIn.Length greater than 65536, e.g. requesting a multi-megabyte region in one call to dump a large buffer or an entire memory mapping.
Common situations: Dumping large heap allocations or file-mapped regions from tooling; clients with hardcoded large defaults; misinterpreting Length as bytes-available rather than request size.
Related errors
- unreadable length: %v
- bad array base address %#x
- no thread with id %d
- invalid Filter pattern: %v
- short read
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/b81bb7ad12023de8.
Report an issue: GitHub.