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
- Calculate the required ULEB128 length before calling: length = (bits.Len64(v) + 6) / 7
- Increase the length parameter to accommodate the value
- Verify the value is within the expected range before encoding
- 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
- Always calculate the required ULEB128 length before encoding: (bits.Len64(v) + 6) / 7
- Use variable-length ULEB128 when the exact length is not constrained
- Add assertions in tests that verify encoding lengths match expectations
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
- corrupt archive
- truncated archive
- corrupt object file
- flag %q triggers external linking
- subprogram DIE high not convertible to uint64
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/996302512d0cd4d9.
Report an issue: GitHub.