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
On Windows (amd64), when writing register values back to a thread's CONTEXT, Delve requires each general-purpose register slot to hold exactly 8 bytes. A Register with a non-nil Bytes field of length other than 8 is rejected.
Source
Thrown at pkg/proc/winutil/regs_amd64_arch.go:332
case regnum.AMD64_R10:
p = &ctx.R10
case regnum.AMD64_R11:
p = &ctx.R11
case regnum.AMD64_R12:
p = &ctx.R12
case regnum.AMD64_R13:
p = &ctx.R13
case regnum.AMD64_R14:
p = &ctx.R14
case regnum.AMD64_R15:
p = &ctx.R15
case regnum.AMD64_Rip:
p = &ctx.Rip
}
if p != nil {
if reg.Bytes != nil && len(reg.Bytes) != 8 {
return fmt.Errorf("wrong number of bytes for register %s (%d)", regnum.AMD64ToName(regNum), len(reg.Bytes))
}
*p = reg.Uint64Val
} else if regNum == regnum.AMD64_Rflags {
ctx.EFlags = uint32(reg.Uint64Val)
} else {
if regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 {
return fmt.Errorf("can not set register %s", regnum.AMD64ToName(regNum))
}
reg.FillBytes()
if len(reg.Bytes) > 16 {
return fmt.Errorf("too many bytes when setting register %s", regnum.AMD64ToName(regNum))
}
copy(ctx.FltSave.XmmRegisters[(regNum-regnum.AMD64_XMM0)*16:], reg.Bytes)
}
return nil
}
View on GitHub (pinned to a23773e6c3)
Solutions
- Ensure reg.Bytes is exactly 8 bytes (or nil so only Uint64Val is used) before setting an amd64 general-purpose register
- Call reg.FillBytes() (as the code does for XMM) to materialize Bytes from Uint64Val, then pad/truncate to 8
- Verify you are not reusing register values read from a 386/x86 (4-byte) context on an amd64 target
- Use the documented RPC SetRegister path instead of hand-building winutil Register structs
Example fix
// before
reg := winutil.Register{RegNum: regnum.AMD64_Rax, Bytes: []byte{1,2,3,4}} // 4 bytes -> error
// after
reg := winutil.Register{RegNum: regnum.AMD64_Rax}
reg.Uint64Val = 0x4141414141414141
reg.FillBytes() // Bytes now len 8
Defensive patterns
Strategy: validation
Validate before calling
// Before writing a GP register on Windows amd64:
if reg.Bytes != nil && len(reg.Bytes) != 8 {
reg.FillBytes(); reg.Bytes = reg.Bytes[:8] // normalize
} Type guard
func validGPReg(reg winutil.Register) bool {
return reg.Bytes == nil || len(reg.Bytes) == 8
} Prevention
- Always construct Register from Uint64Val and call FillBytes()
- Never reuse 4-byte (386) register data on amd64 targets
- Only copy register contexts captured from the same architecture
When it happens
Trigger: Calling SetRegs/WriteRegisters (e.g. via a debugger client setting a register) with a Register whose Bytes slice was populated with a length != 8, such as a 4-byte value from a 32-bit-style read or a truncated buffer.
Common situations: Custom tooling that constructs Register structs by hand for Windows targets; mixing register data captured from a different architecture; partial register writes where only low bytes were captured.
Related errors
- can not set register %s
- too many bytes when setting register %s
- can not change register values of core process
- hardware breakpoints not supported
- wrong number of bytes for register %s (%d)
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/80d5cdd80677e892.
Report an issue: GitHub.