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, errView on GitHub (pinned to 93e97f4bf1)
Solutions
- Ensure you created the client via NewClient and the initial Connect/Login succeeded before calling HealthCheck
- Check the management service is reachable (correct host:port, TLS setup) and restart or re-dial the connection, then retry the health check
- 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
- Always handle the error returned by client creation/Connect before using the client
- Prefer IsHealthy() for background monitoring and reserve HealthCheck() for pre-commit validation of an established connection
- Retry with backoff around reconnect+healthcheck when management restarts
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
- login backoff cycle failed: %v
- unable to get daemon status: %v
- dial context: %w
- unexpected config protocol type %v
- management client is not initialised
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/6527088b7edf1eeb.
Report an issue: GitHub.