AlexxIT/go2rtc · error

write av login response

Error message

write av login response: %w

What it means

AVServStart computes the login response from the request checksum and writes it back; a failure of that Write is wrapped with this error and the server connection is closed. It means the host could not deliver the AV login acceptance to the camera.

Solutions

  1. Inspect the wrapped cause to distinguish timeout vs closed connection
  2. Retry the full intercom start sequence (DTLS handshake + login exchange)
  3. Check network stability between host and camera
  4. Ensure no other goroutine is closing the DTLS conn concurrently
Defensive patterns

Strategy: retry

Validate before calling

if conn == nil || conn.IsClosed() {
	return fmt.Errorf("intercom session closed before response")
}

Try / catch

if err := conn.AVServStart(); err != nil {
	if errors.Is(err, net.ErrClosed) {
		// camera dropped; restart full intercom sequence
	}
	return err
}

Prevention

When it happens

Trigger: StartIntercom -> AVServStart when conn.Write(resp) fails after receiving a valid AV login request — DTLS session closed by the camera, deadline exceeded, or transport error.

Common situations: Camera dropped the connection right after sending the login request; network interruption during two-way audio setup; DTLS rekey/close happening concurrently.

Related errors


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

Appendix: source

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

	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")
	}

	// Camera may resend, respond again
	conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
	if n, _ = conn.Read(buf); n > 0 {
		if c.verbose {
			fmt.Printf("[SERVER] Received AV Login resend: %d bytes\n", n)
		}
		conn.Write(resp)
	}

	conn.SetReadDeadline(time.Time{})

	if c.verbose {

View on GitHub (pinned to c245815e75)