AlexxIT/go2rtc · error

wyze: K10003 parse failed

Error message

wyze: K10003 parse failed: %w

What it means

After the K10002/K10003 exchange, doKAuth parses the K10003 auth-result payload with parseK10003. If the payload cannot be parsed (missing/malformed HL framing or fields), the error is wrapped as "wyze: K10003 parse failed".

Solutions

  1. Enable verbose mode and log the raw HL bytes to see the actual K10003 payload.
  2. Verify UID/authKey/enr are valid — rejections often come back in an unexpected shape.
  3. Check the wrapped parse error for specifics (missing magic, short data) and compare with the expected K10003 schema.
  4. Retry once; if reproducible, the camera's firmware response format likely needs a library update.
Defensive patterns

Strategy: validation

Try / catch

if err := client.Dial(); err != nil {
    if strings.Contains(err.Error(), "K10003 parse failed") {
        return fmt.Errorf("camera rejected auth in unexpected format — check credentials/firmware: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Camera sent a K10003 whose HL payload doesn't match the expected structure; error/status frame returned instead of a normal auth result; truncated packet received.

Common situations: Firmware sending an auth-rejection payload with a different layout; wrong credentials leading to an alternate response shape; protocol drift after a camera firmware update.

Related errors


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

Appendix: source

Thrown at pkg/wyze/client.go:362

	if err != nil {
		return fmt.Errorf("wyze: K10001 parse failed: %w", err)
	}

	if c.verbose {
		fmt.Printf("[Wyze] K10001 challenge received, status=%d\n", status)
	}

	// Step 2: K10002 -> K10003 (Auth)
	data, err = c.conn.WriteAndWaitIOCtrl(c.buildK10002(challenge, status), c.matchHL(KCmdAuthResult), 5*time.Second)
	if err != nil {
		return fmt.Errorf("wyze: K10002 failed: %w", err)
	}
	hlData = c.extractHL(data)

	// Parse K10003 response
	authResp, err := c.parseK10003(hlData)
	if err != nil {
		return fmt.Errorf("wyze: K10003 parse failed: %w", err)
	}

	if c.verbose && authResp != nil {
		if jsonBytes, err := json.MarshalIndent(authResp, "", "  "); err == nil {
			fmt.Printf("[Wyze] K10003 response:\n%s\n", jsonBytes)
		}
	}

	// Extract audio capability from cameraInfo
	if authResp != nil && authResp.CameraInfo != nil {
		if channelResult, ok := authResp.CameraInfo["channelRequestResult"].(map[string]any); ok {
			if audio, ok := channelResult["audio"].(string); ok {
				c.hasAudio = audio == "1"
			} else {
				c.hasAudio = true
			}
		} else {
			c.hasAudio = true

View on GitHub (pinned to c245815e75)