AlexxIT/go2rtc · error

failed to start MQTT

Error message

failed to start MQTT: %w

What it means

Wraps an error from mqtt.Start() after Tuya cloud configs were successfully loaded. The MQTT layer connects to the Tuya hub broker using hubConfig to exchange WebRTC signaling. Any connect, TLS, auth, or subscribe failure surfaces as this error.

Solutions

  1. Inspect the wrapped inner error for connect vs TLS vs auth failure
  2. Verify outbound access to the Tuya MQTT broker host:port from this network
  3. Re-fetch config/token; re-pair or re-authenticate the device if credentials were rotated
  4. Confirm region/countryCode matches the account so hubConfig contains valid broker endpoints
  5. Check DNS resolution of the broker hostname on the host running go2rtc

Example fix

// before
if err := c.mqtt.Start(hubConfig, webrtcConfig, skill.WebRTC); err != nil {
    return fmt.Errorf("failed to start MQTT: %w", err)
}
// after
if err := c.mqtt.Start(hubConfig, webrtcConfig, skill.WebRTC); err != nil {
    log.Errorf("mqtt start failed (broker=%s): %v", hubConfig.Broker, err) // surface broker for diagnosis
    return fmt.Errorf("failed to start MQTT: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// Go: pre-check broker reachability before Start
conn, err := net.DialTimeout("tcp", brokerHost+":"+brokerPort, 5*time.Second)
if err != nil { return fmt.Errorf("mqtt broker unreachable: %w", err) }
conn.Close()

Type guard

func hubConfigValid(cfg *tuya.HubConfig) bool { return cfg != nil && cfg.Broker != "" && cfg.Port > 0 }

Try / catch

if err := c.Start(); err != nil {
    if strings.Contains(err.Error(), "failed to start MQTT") {
        return retryWithBackoff(3, c.Start) // transient network failures
    }
    return err
}

Prevention

When it happens

Trigger: TuyaSmartAPI Start() when the MQTT client cannot connect/authenticate to the broker from hubConfig: wrong broker host/port, TLS handshake failure, credentials rejected, or network unreachable.

Common situations: Firewall or ISP blocking the MQTT port; stale hub credentials after re-pairing the device; DNS failure resolving the broker hostname; hubConfig fetched from the wrong region so broker endpoints are invalid.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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

Appendix: source

Thrown at pkg/tuya/smart_api.go:314

// WebRTC Flow
func (c *TuyaSmartApiClient) Init() error {
	if err := c.initToken(); err != nil {
		return fmt.Errorf("failed to initialize token: %w", err)
	}

	webrtcConfig, err := c.loadWebrtcConfig()
	if err != nil {
		return fmt.Errorf("failed to load webrtc config: %w", err)
	}

	hubConfig, err := c.loadHubConfig()
	if err != nil {
		return fmt.Errorf("failed to load hub config: %w", err)
	}

	if err := c.mqtt.Start(hubConfig, webrtcConfig, c.skill.WebRTC); err != nil {
		return fmt.Errorf("failed to start MQTT: %w", err)
	}

	if c.skill.LowPower > 0 {
		_ = c.mqtt.WakeUp(c.localKey)
	}

	return nil
}

func (c *TuyaSmartApiClient) GetStreamUrl(streamType string) (streamUrl string, err error) {
	return "", errors.New("not supported")
}

func (c *TuyaSmartApiClient) GetAppInfo() (*AppInfoResponse, error) {
	url := fmt.Sprintf("https://%s/api/customized/web/app/info", c.baseUrl)

	body, err := c.request("POST", url, nil)
	if err != nil {

View on GitHub (pinned to c245815e75)