AlexxIT/go2rtc · error

av login too short: bytes

Error message

av login too short: %d bytes

What it means

AVServStart validates the received AV login request is at least 24 bytes so it can read the checksum at offset 20. If the packet is shorter, the library refuses to parse it and closes the connection. It indicates a malformed or unexpected AV login packet from the camera.

Solutions

  1. Log the raw bytes (hexDump) and compare with the expected AV login layout
  2. Check camera firmware version vs the protocol version this library implements
  3. Buffer/coalesce reads until at least 24 bytes are available if the transport fragments packets
  4. Verify you are reading on the correct channel (iotcChannelBack)

Example fix

// before
if n < 24 {
	go conn.Close()
	return fmt.Errorf("av login too short: %d bytes", n)
}
// after
for n < 24 {
	m, err := conn.Read(buf[n:])
	if err != nil {
		go conn.Close()
		return fmt.Errorf("av login too short after re-read: %d bytes: %w", n, err)
	}
	n += m
}
Defensive patterns

Strategy: validation

Validate before calling

// after read: validate before use
if n < 24 {
	// accumulate more reads or treat as protocol error
}

Type guard

func isValidAVLogin(buf []byte, n int) bool {
	return n >= 24
}

Try / catch

if err := conn.AVServStart(); err != nil {
	if strings.Contains(err.Error(), "av login too short") {
		// log hexDump, check firmware compatibility
	}
}

Prevention

When it happens

Trigger: StartIntercom -> AVServStart when the first packet received after the DTLS handshake is smaller than 24 bytes — e.g. a DTLS control artifact, a partial read, or a non-AV-login message arriving first.

Common situations: Firmware protocol mismatch (older/newer camera sending a different login layout); fragmentation causing a short first read; wrong channel receiving unexpected data.

Related errors


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/2621388b600ab519. Report an issue: GitHub.

Appendix: source

Thrown at pkg/tutk/dtls/conn_dtls.go:255

		fmt.Printf("[SERVER] Waiting for AV Login request from camera...\n")
	}

	// Wait for AV Login request from camera
	buf := make([]byte, 1024)
	conn.SetReadDeadline(time.Now().Add(5 * time.Second))
	n, err := conn.Read(buf)
	if err != nil {
		go conn.Close()
		return fmt.Errorf("read av login: %w", err)
	}

	if c.verbose {
		fmt.Printf("[SERVER] AV Login request len=%d data:\n%s", n, hexDump(buf[:n]))
	}

	if n < 24 {
		go conn.Close()
		return fmt.Errorf("av login too short: %d bytes", n)
	}

	checksum := binary.LittleEndian.Uint32(buf[20:])
	resp := c.msgAVLoginResponse(checksum)

	if c.verbose {
		fmt.Printf("[SERVER] Sending AV Login response: %d bytes\n", len(resp))
	}

	if _, err = conn.Write(resp); err != nil {
		go conn.Close()
		return fmt.Errorf("write av login response: %w", err)
	}

	if c.verbose {
		fmt.Printf("[SERVER] AV Login response sent, waiting for possible resend...\n")
	}

View on GitHub (pinned to c245815e75)