AlexxIT/go2rtc · error
tlv8: wrong size:
Error message
tlv8: wrong size:
What it means
unmarshalTLV reads a TLV8 record that must contain at least a 1-byte tag and a 1-byte length header. If fewer than 2 bytes remain in the buffer (0 or 1 byte), the record header cannot be read, so it returns nil bytes plus this "wrong size" error naming the destination type. Returning nil marks the error as critical, so unmarshalStruct aborts the whole decode.
Solutions
- Verify the input payload length is even and complete before calling Unmarshal: len(data)%2 == 0 for simple TLV8, and each record consumes 2+L bytes.
- Check for truncation upstream: if using UnmarshalReader with n, confirm io.ReadFull consumed all n bytes and that n matches the actual record.
- Log/reject malformed peer data at the protocol layer (HAP pairing) and restart the pairing/verification session rather than retrying the same bytes.
- Validate the base64 input decodes without error and contains no stray characters before UnmarshalBase64.
Example fix
// before
tlv8.UnmarshalReader(resp.Body, -1, &out) // reads all, even truncated garbage
// after
var n int64 = declaredLen
data, _ := io.ReadAll(resp.Body)
if int64(len(data)) < n {
return fmt.Errorf("tlv8 payload truncated: got %d want %d", len(data), n)
}
tlv8.Unmarshal(data, &out) Defensive patterns
Strategy: validation
Validate before calling
func validTLV8Framing(data []byte) bool {
for i := 0; i < len(data); {
if len(data)-i < 2 {
return false // truncated header
}
l := int(data[i+1])
i += 2 + l
}
return true
}
// call validTLV8Framing(data) before tlv8.Unmarshal(data, &out) Try / catch
if !validTLV8Framing(data) {
return errors.New("refusing to decode truncated tlv8 payload")
}
if err := tlv8.Unmarshal(data, &out); err != nil {
if strings.Contains(err.Error(), "tlv8: wrong size") {
return fmt.Errorf("corrupt tlv8 payload from peer: %w", err)
}
return err
} Prevention
- Always read the complete transport payload (check Content-Length / io.ReadFull results) before decoding.
- Pass the correct n to UnmarshalReader, or 0 to consume the whole reader.
- Validate base64 inputs decode cleanly and have expected length before UnmarshalBase64.
- Treat malformed TLV8 from a peer as a protocol violation: abort the session, log, and restart pairing.
When it happens
Trigger: Decoding a truncated TLV8 payload — e.g. data ending in a single stray byte after the last valid record, a payload cut off mid-record by a partial HTTP body read, or a base64 string that decodes to an odd trailing byte — passed to Unmarshal (and thus Dial/Pair/PairSetup/PairVerify).
Common situations: Reading a fixed-length HAP response with UnmarshalReader using a wrong `n` so the tail is truncated; base64 payload manually edited or copy-pasted incompletely; a peer sending malformed/malicious TLV8 data; concatenating payloads and losing a byte.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- tlv8: value should be pointer:
- tlv8: zero item
- tlv8: can't find T= ,L= ,V= for
- tlv8: unmarshal zero data
- streams: source empty
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/32d933d4ef8701e9.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/hap/tlv8/tlv8.go:229
kind = value.Kind()
}
switch kind {
case reflect.Slice:
return unmarshalSlice(data, value)
case reflect.Struct:
return unmarshalStruct(data, value)
}
return errors.New("tlv8: not implemented: " + kind.String())
}
// unmarshalTLV can return two types of errors:
// - critical and then the value of []byte will be nil
// - not critical and then []byte will contain the value
func unmarshalTLV(b []byte, value reflect.Value) ([]byte, error) {
if len(b) < 2 {
return nil, errors.New("tlv8: wrong size: " + value.Type().Name())
}
t := b[0]
l := int(b[1])
// array item divider (t == 0x00 || t == 0xFF)
if l == 0 {
return b[2:], errors.New("tlv8: zero item")
}
var v []byte
for {
if len(b) < 2+l {
return nil, errors.New("tlv8: wrong size: " + value.Type().Name())
}
v = append(v, b[2:2+l]...)View on GitHub (pinned to c245815e75)