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
- Inspect the wrapped cause to distinguish timeout vs closed connection
- Retry the full intercom start sequence (DTLS handshake + login exchange)
- Check network stability between host and camera
- 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
- Restart the whole intercom flow after a response-write failure
- Avoid concurrent Close calls on the DTLS conn
- Check network stability for two-way audio sessions
- Use verbose logging to spot camera-side disconnects early
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
- av login 1 failed
- av login 2 failed
- dtls: server handshake failed
- read av login
- dtls: client handshake failed
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)