netbirdio/netbird · error

sync response persistence is disabled

Error message

sync response persistence is disabled

What it means

handleClientStatus (proxy/internal/debug/handler.go:431) got a live client but client.Status() returned an error, and the handler answers 500 with the error text appended. Status() aggregates the embedded client's internal state, so a non-nil error means the client could not produce its status — typically because its management stream/sync machinery is in a failed state.

Source

Thrown at client/internal/engine.go:2419

		if err := e.syncStore.Clear(); err != nil {
			log.Warnf("failed to clear persisted sync response: %v", err)
		}
		e.syncStore = nil
		return
	}

	e.syncStore = syncstore.New(e.syncStoreDir)
}

// GetLatestSyncResponse returns the stored sync response if persistence is enabled
func (e *Engine) GetLatestSyncResponse() (*mgmProto.SyncResponse, error) {
	// Hold the lock for the whole Get so the store cannot be cleared
	// (disabled / engine close) mid-call.
	e.syncRespMux.RLock()
	defer e.syncRespMux.RUnlock()

	if e.syncStore == nil {
		return nil, errors.New("sync response persistence is disabled")
	}

	//nolint:nilnil
	return e.syncStore.Get()
}

// GetWgAddr returns the wireguard address
func (e *Engine) GetWgAddr() netip.Addr {
	if e.wgInterface == nil {
		return netip.Addr{}
	}
	return e.wgInterface.Address().IP
}

// GetWgV6Addr returns the IPv6 overlay address of the WireGuard interface.
func (e *Engine) GetWgV6Addr() netip.Addr {
	if e.wgInterface == nil {
		return netip.Addr{}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Read the appended err.Error() in the response body — it states whether the failure is the management connection or internal state.
  2. Check the clients overview / health endpoints to see if the account's client is connected at all.
  3. Retry once the client re-establishes its management sync; if stuck, restart the proxy or the affected account's client.
Defensive patterns

Strategy: retry

Try / catch

// Status collection can fail transiently while the client reconnects.
for i := 0; i < 3; i++ {
    resp, err := http.Get(statusURL)
    if err == nil && resp.StatusCode == http.StatusOK {
        break
    }
    time.Sleep(2 * time.Second)
}

Prevention

When it happens

Trigger: Calling the status debug endpoint while the per-account client's connection to management is broken (gRPC stream down, login expired) or its internal collectors returned an error; the client exists in the registry but is unhealthy.

Common situations: Inspecting a client mid-reconnect; management temporarily unreachable so status collection fails; client shutting down concurrently with the status call.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/5defb1c35b366395. Report an issue: GitHub.