go-delve/delve · error

Could not parse ULEB128 value

Error message

Could not parse ULEB128 value

What it means

leb128.DecodeUnsigned panics with "Could not parse ULEB128 value" when the byte reader hits EOF before a terminating byte (high bit 0) is found. A ULEB128 value must end with a byte whose high-order bit is clear; running out of bytes means the encoded value is truncated or the buffer is misaligned. The library treats malformed LEB128 data as a programming error and panics instead of returning an error.

Source

Thrown at pkg/dwarf/leb128/decode.go:31

}

// DecodeUnsigned decodes an unsigned Little Endian Base 128
// represented number.
func DecodeUnsigned(buf Reader) (uint64, uint32) {
	var (
		result uint64
		shift  uint64
		length uint32
	)

	if buf.Len() == 0 {
		return 0, 0
	}

	for {
		b, err := buf.ReadByte()
		if err != nil {
			panic("Could not parse ULEB128 value")
		}
		length++

		result |= uint64((uint(b) & 0x7f) << shift)

		// If high order bit is 1.
		if b&0x80 == 0 {
			break
		}

		shift += 7
	}

	return result, length
}

// DecodeSigned decodes a signed Little Endian Base 128
// represented number.

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Ensure the byte slice passed to DecodeUnsigned starts exactly at the encoded value and contains its complete bytes.
  2. Validate the enclosing DWARF section is not truncated (check section length vs. offsets).
  3. Wrap the call in defer/recover if parsing untrusted data, converting the panic into an error.
  4. Regenerate or re-obtain the binary/core with intact debug info.

Example fix

// before
val, _ := leb128.DecodeUnsigned(buf) // panics on truncated input
// after
func safeDecodeUleb(buf *bytes.Buffer) (val uint64, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("truncated ULEB128: %v", r)
		}
	}()
	val, _ = leb128.DecodeUnsigned(buf)
	return val, nil
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: verify buffer bounds before decoding ULEB128
func hasTerminator(b []byte) bool {
	for _, c := range b {
		if c&0x80 == 0 { return true }
	}
	return false // would trigger "Could not parse ULEB128 value"
}

Try / catch

// Go
func decodeU(buf *bytes.Buffer) (v uint64, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("truncated ULEB128: %v", r)
		}
	}()
	v, _ = leb128.DecodeUnsigned(buf)
	return v, nil
}

Prevention

When it happens

Trigger: Calling DecodeUnsigned with a buffer that ends while the continuation bit (0x80) is still set — e.g. a truncated DWARF field, a wrong starting offset, or decoding non-LEB128 data as LEB128.

Common situations: Corrupt or truncated DWARF sections in binaries/cores; off-by-one offsets when manually walking DWARF structures; attempting to parse data produced by a different encoder at a wrong position.

Related errors


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