netbirdio/netbird · error

no connection to management

Error message

no connection to management

What it means

Returned by GrpcClient.HealthCheck (shared/management/client/grpc.go:488): the method first checks c.ready(), which requires the underlying gRPC connection state to be Ready or Idle (grpc.go:183-185). If the transport is in TransientFailure, Connecting, or Shutdown, the probe is skipped and this error is returned before any RPC goes out.

Source

Thrown at shared/management/client/grpc.go:488

		log.Debugf("got an update message from Management Service")
		decryptedResp := &proto.SyncResponse{}
		err = encryption.DecryptMessage(serverPubKey, c.key, update.Body, decryptedResp)
		if err != nil {
			log.Errorf("failed decrypting update message from Management Service: %s", err)
			return err
		}

		if err := msgHandler(decryptedResp); err != nil {
			log.Errorf("failed handling an update message received from Management Service: %v", err.Error())
		}
	}
}

// HealthCheck actively probes the management server and returns an error if unreachable.
// Used to validate connectivity before committing configuration changes.
func (c *GrpcClient) HealthCheck() error {
	if !c.ready() {
		return errors.New(errMsgNoMgmtConnection)
	}

	_, err := c.getServerPublicKey()
	return err
}

// getServerPublicKey fetches the server's WireGuard public key.
func (c *GrpcClient) getServerPublicKey() (*wgtypes.Key, error) {
	mgmCtx, cancel := context.WithTimeout(c.ctx, 5*time.Second)
	defer cancel()
	resp, err := c.realClient.GetServerKey(mgmCtx, &proto.Empty{})
	if err != nil {
		return nil, fmt.Errorf("failed getting Management Service public key: %w", err)
	}

	serverKey, err := wgtypes.ParseKey(resp.Key)
	if err != nil {
		return nil, err

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Ensure you created the client via NewClient and the initial Connect/Login succeeded before calling HealthCheck
  2. Check the management service is reachable (correct host:port, TLS setup) and restart or re-dial the connection, then retry the health check
  3. Treat this error as 'not connected' rather than 'server unhealthy': reconnect instead of probing

Example fix

// before
client, _ := client.NewClient(ctx, mgmAddr, nil)
err := client.HealthCheck() // no connection to management

// after
client, err := client.NewClient(ctx, mgmAddr, nil)
if err != nil { return err }
if err := client.Connect(ctx, ...); err != nil { return err } // establish transport first
err = client.HealthCheck()
Defensive patterns

Strategy: retry

Validate before calling

// Use the non-probing status check first
if !client.IsHealthy() { // never returns this error; checks conn state + IsHealthy RPC
    // reconnect before probing
}

Try / catch

err := client.HealthCheck()
if err != nil {
    if strings.Contains(err.Error(), "no connection to management") {
        // transport is down: reconnect (Connect/backoff), then retry once ready;
        // do not treat this specific error as 'server unhealthy'
    }
    return err
}

Prevention

When it happens

Trigger: Calling HealthCheck before a successful client.Connect, after the connection has dropped (server down, network change, TLS failure), or after Stop() closed the client. Distinguished from a probe failure: here the client already knows it has no usable transport.

Common situations: Using the client in code that skips the Connect error; management service restarting while the agent polls; misconfigured management URL or port so the connection never became ready; firewall blocking gRPC.

Related errors


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