golang/go · error

writeUleb128FixedLength: length too small

Error message

writeUleb128FixedLength: length too small

What it means

The writeUleb128FixedLength function encodes a uint64 value as ULEB128 (Unsigned Little Endian Base 128) into a fixed-size byte slice of exactly 'length' bytes. Each ULEB128 byte encodes 7 bits of the value, so 'length' bytes can represent values up to (2^(7*length)) - 1. If the value exceeds this capacity after consuming all bytes, the error fires.

Source

Thrown at src/cmd/link/internal/ld/data.go:3461

// writeUleb128FixedLength writes out value v in LEB128 encoded
// format, ensuring that the space written takes up length bytes. When
// extra space is needed, we write initial bytes with just the
// continuation bit set. For example, if val is 1 and length is 3,
// we'll write 0x80 0x80 0x1 (first two bytes with zero val but
// continuation bit set). NB: this function adapted from a similar
// function in cmd/link/internal/wasm, they could be commoned up if
// needed.
func writeUleb128FixedLength(b []byte, v uint64, length int) error {
	for i := 0; i < length; i++ {
		c := uint8(v & 0x7f)
		v >>= 7
		if i < length-1 {
			c |= 0x80
		}
		b[i] = c
	}
	if v != 0 {
		return fmt.Errorf("writeUleb128FixedLength: length too small")
	}
	return nil
}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Calculate the required ULEB128 length before calling: length = (bits.Len64(v) + 6) / 7
  2. Increase the length parameter to accommodate the value
  3. Verify the value is within the expected range before encoding
  4. Report as a Go linker bug if the caller is internal linker code

Example fix

// before
err := writeUleb128FixedLength(buf, 300, 1) // fails: 300 needs 2 bytes

// after
err := writeUleb128FixedLength(buf, 300, 2) // succeeds
Defensive patterns

Strategy: validation

Validate before calling

// Validate that the value fits in the given ULEB128 length before encoding
func fitsInULEB128(v uint64, length int) bool {
    for i := 0; i < length; i++ {
        v >>= 7
    }
    return v == 0
}

// Or compute the required length:
func requiredULEB128Length(v uint64) int {
    if v == 0 {
        return 1
    }
    return (bits.Len64(v) + 6) / 7
}

Try / catch

// Handle encoding failures by resizing
if err := writeUleb128FixedLength(buf, v, length); err != nil {
    length = requiredULEB128Length(v)
    if err := writeUleb128FixedLength(buf, v, length); err != nil {
        return err // genuinely too large
    }
}

Prevention

When it happens

Trigger: The function writes 'length' bytes of ULEB128 encoding into buffer b. After the loop, if v != 0 (the value has not been fully consumed), it means the value requires more ULEB128 bytes than provided. For example, encoding 300 (which needs 2 ULEB128 bytes) into a 1-byte buffer triggers this error.

Common situations: Internal linker code miscalculates the required ULEB128 length for a value; a buffer size assumption is violated by an unexpectedly large value; changes to data structures that increase value ranges without updating the encoding length.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/996302512d0cd4d9. Report an issue: GitHub.