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

  1. Ensure reg.Bytes is exactly 8 bytes long before calling SetReg (or leave Bytes nil and set Uint64Val, letting reg.FillBytes() handle it)
  2. Call reg.FillBytes() on the Variable to normalize the byte slice before invoking SetReg
  3. 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

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


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/480efd7f7bee36dc. Report an issue: GitHub.