AlexxIT/go2rtc · error
av login 1 failed
Error message
av login 1 failed: %w
What it means
AVClientStart performs a two-stage AV login by writing two crafted login packets to the client connection. If the first packet write fails, the error is wrapped as 'av login 1 failed: %w' preserving the underlying cause. This is a transport-level failure, not an application-level login rejection.
Solutions
- Inspect the wrapped error (%w) to identify the transport cause and fix it (reconnect, re-handshake, network).
- Re-create the connection (Dial + DTLS handshake) before retrying AVClientStart — writes on a dead conn will keep failing.
- Verify the device is reachable and its AV server port is open before initiating login.
- Add retry with backoff around AVClientStart for transient network blips.
Example fix
// before
if err := doAVLogin(conn); err != nil { return err }
// after
if err := doAVLogin(conn); err != nil {
conn, cerr := redial() // fresh Dial + handshake
if cerr != nil { return cerr }
return doAVLogin(conn)
} Defensive patterns
Strategy: retry
Validate before calling
// Ensure transport is writable before login
if err := conn.Ping(); err != nil {
return fmt.Errorf("transport not ready for AV login: %w", err)
} Try / catch
err := doAVLogin(conn)
if err != nil && strings.Contains(err.Error(), "av login 1 failed") {
conn, rerr := redial() // fresh Dial + handshake
if rerr != nil { return rerr }
return retry.Do(3, time.Second, func() error { return doAVLogin(conn) })
} Prevention
- Verify device reachability before initiating AV login
- Redial dead sessions instead of reusing them
- Add retry with backoff around login for transient blips
- Log the wrapped transport error to distinguish offline vs blocked
When it happens
Trigger: Calling AVClientStart (via doAVLogin) when c.clientConn.Write(pkt1) returns an error — connection closed, DTLS/UDP write failure, or the underlying session already dead.
Common situations: Device went offline between connect and login; underlying DTLS handshake/transport not ready; firewall blocking outbound packets; session torn down by a previous timeout while the object is reused.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/d45ed377dd097186.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/tutk/dtls/conn_dtls.go:177
if err = c.connect(); err != nil {
_ = c.Close()
return nil, err
}
c.wg.Add(1)
go c.worker()
return c, nil
}
func (c *DTLSConn) AVClientStart(timeout time.Duration) error {
randomID := tutk.GenSessionID()
pkt1 := c.msgAVLogin(magicAVLogin1, 570, 0x0001, randomID)
pkt2 := c.msgAVLogin(magicAVLogin2, 572, 0x0000, randomID)
pkt2[20]++ // pkt2 has randomID incremented by 1
if _, err := c.clientConn.Write(pkt1); err != nil {
return fmt.Errorf("av login 1 failed: %w", err)
}
time.Sleep(10 * time.Millisecond)
if _, err := c.clientConn.Write(pkt2); err != nil {
return fmt.Errorf("av login 2 failed: %w", err)
}
// Wait for response
timer := time.NewTimer(timeout)
defer timer.Stop()
for {
select {
case data, ok := <-c.rawCmd:
if !ok {
return io.EOF
}
if len(data) >= 32 && binary.LittleEndian.Uint16(data) == magicAVLoginResp {View on GitHub (pinned to c245815e75)