go-delve/delve · error
wrong number of bytes for register %s (%d)
Error message
wrong number of bytes for register %s (%d)
What it means
SetReg validates that register values supplied by callers carry exactly 8 bytes before writing them into the amd64 ptrace register set. A register whose byte slice has a length other than 8 is inconsistent with the fixed 64-bit width of general-purpose amd64 registers, so SetReg refuses to write it rather than corrupting process state.
Source
Thrown at pkg/proc/linutil/regs_amd64_arch.go:203
case regnum.AMD64_R11:
p = &r.Regs.R11
case regnum.AMD64_R12:
p = &r.Regs.R12
case regnum.AMD64_R13:
p = &r.Regs.R13
case regnum.AMD64_R14:
p = &r.Regs.R14
case regnum.AMD64_R15:
p = &r.Regs.R15
case regnum.AMD64_Rip:
p = &r.Regs.Rip
case regnum.AMD64_Rflags:
p = &r.Regs.Eflags
}
if p != nil {
if reg.Bytes != nil && len(reg.Bytes) != 8 {
return false, fmt.Errorf("wrong number of bytes for register %s (%d)", regnum.AMD64ToName(regNum), len(reg.Bytes))
}
*p = reg.Uint64Val
return false, nil
}
if r.loadFpRegs != nil {
err := r.loadFpRegs(r)
if err != nil {
return false, err
}
r.loadFpRegs = nil
}
if regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 {
return false, fmt.Errorf("can not set %s", regnum.AMD64ToName(regNum))
}
reg.FillBytes()View on GitHub (pinned to a23773e6c3)
Solutions
- Ensure reg.Bytes is exactly 8 bytes long before calling SetReg (or leave Bytes nil and set Uint64Val, letting reg.FillBytes() handle it)
- Call reg.FillBytes() on the Variable to normalize the byte slice before invoking SetReg
- Check the caller (RPC client / API layer) for register payloads that were truncated or serialized incorrectly
Example fix
// before
reg.Bytes = []byte{0x01, 0x02} // 2 bytes
thread.SetReg(regnum.AMD64_Rax, reg)
// after
reg.Bytes = nil
reg.Uint64Val = 0x1234
reg.FillBytes() // produces 8 bytes
thread.SetReg(regnum.AMD64_Rax, reg) Defensive patterns
Strategy: validation
Validate before calling
if reg.Bytes != nil && len(reg.Bytes) != 8 {
return fmt.Errorf("register %s requires exactly 8 bytes, got %d", regnum.AMD64ToName(regNum), len(reg.Bytes))
}
reg.FillBytes() Type guard
func isValidGPRBytes(reg *proc.Variable) bool {
return reg.Bytes == nil || len(reg.Bytes) == 8
} Try / catch
if err := thread.SetReg(regNum, reg); err != nil {
if strings.Contains(err.Error(), "wrong number of bytes") {
reg.FillBytes()
err = thread.SetReg(regNum, reg)
}
return err
} Prevention
- Always call FillBytes() on register Variables before SetReg
- Never hand-craft register byte slices; set Uint64Val and let the library normalize
- Validate register payloads at API boundaries (RPC clients) before sending
When it happens
Trigger: Calling proc.SetReg on a Linux/amd64 thread with a Variable representing a general-purpose register (e.g. Rax, Rip, Rflags) whose reg.Bytes slice is non-nil but has length != 8.
Common situations: Clients building register Variables by hand from protocol data (e.g. RPC layer passing partial/truncated register bytes), or frontend tools that fill only some bytes of a register before issuing a register-set request.
Related errors
- could not restore registers: %v
- could not restore RFLAGS register: %v
- can not set %s
- changing register %d not implemented
- changing register %d not implemented
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/480efd7f7bee36dc.
Report an issue: GitHub.