go-delve/delve · error

too many bytes when setting register %s

Error message

too many bytes when setting register %s

What it means

In Delve's Windows AMD64 backend, setting a register via SetReg validates the value being written. For XMM registers (regnum.AMD64_XMM0..+15), after calling reg.FillBytes() the byte slice must be at most 16 bytes (128-bit XMM width); a longer value cannot fit in the XMM register slot in CONTEXT.FltSave, so this error is thrown instead of truncating or corrupting memory.

Source

Thrown at pkg/proc/winutil/regs_amd64_arch.go:343

		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

  1. Ensure the register value is at most 16 bytes before calling SetReg (truncate/mask the value to 128 bits).
  2. Verify you are targeting an XMM register and not expecting YMM/ZMM writes, which this backend does not support.
  3. If writing a general-purpose register instead, use the non-XMM code path (regNum outside AMD64_XMM0..+15) where different sizing applies.
  4. Check the byte encoding used to build reg (FillBytes output) — a wrong size value in the register value struct inflates Bytes length.

Example fix

// before
reg.FillBytes() // reg.Bytes is 32 bytes (YMM-sized value)
copy(ctx.FltSave.XmmRegisters[(regNum-regnum.AMD64_XMM0)*16:], reg.Bytes)
// after
reg.FillBytes()
if len(reg.Bytes) > 16 {
    reg.Bytes = reg.Bytes[:16] // fit XMM 128-bit width
}
copy(ctx.FltSave.XmmRegisters[(regNum-regnum.AMD64_XMM0)*16:], reg.Bytes)
Defensive patterns

Strategy: validation

Validate before calling

reg.FillBytes()
if len(reg.Bytes) > 16 {
    return fmt.Errorf("value too large for XMM register: %d bytes (max 16)", len(reg.Bytes))
}

Type guard

func isSettableXMMValue(reg proc.RegisterValue) bool {
    b := reg.Bytes
    return b == nil || len(b) <= 16
}

Try / catch

if err := thread.SetReg(regNum, reg); err != nil {
    if strings.Contains(err.Error(), "too many bytes when setting register") {
        // fallback: mask value to 128 bits and retry
    }
    return err
}

Prevention

When it happens

Trigger: Calling the debugger's SetReg API on a Windows amd64 target with a register value whose serialized byte representation exceeds 16 bytes, targeting an XMM register (XMM0-XMM15). This happens if the caller supplies a value typed as a larger vector/register (e.g. 256-bit AVX or 512-bit ZMM data) or a wrongly-filled register value struct.

Common situations: Users or tools attempting to modify vector registers from scripts/RPC with oversized values; automation that fills reg.Bytes from a wider register dump; copy-pasted code assuming YMM/ZMM support which Delve's Windows backend does not implement.

Related errors


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