kubernetes/kops · error

deregistering cloud instance %s of group %q: %w

Error message

deregistering cloud instance %s of group %q: %w

What it means

DeregisterInstance removes a node from Scaleway load-balancers before it leaves the cluster. The first step fetches the server with instanceAPI.GetServer; any non-nil error is wrapped as "deregistering cloud instance %s of group %q: %w". Unlike DeleteInstance there is no 404 special-casing here, so an already-deleted instance also fails deregistration.

Source

Thrown at upup/pkg/fi/cloudup/scaleway/cloud.go:260

		}
		return fmt.Errorf("deleting cloud instance %s of group %s: %w", i.ID, i.CloudInstanceGroup.HumanName, err)
	}

	err = s.DeleteServer(server.Server)
	if err != nil {
		return fmt.Errorf("deleting cloud instance %s of group %s: %w", i.ID, i.CloudInstanceGroup.HumanName, err)
	}

	return nil
}

func (s *scwCloudImplementation) DeregisterInstance(i *cloudinstances.CloudInstance) error {
	server, err := s.instanceAPI.GetServer(&instance.GetServerRequest{
		Zone:     s.zone,
		ServerID: i.ID,
	})
	if err != nil {
		return fmt.Errorf("deregistering cloud instance %s of group %q: %w", i.ID, i.CloudInstanceGroup.HumanName, err)
	}
	serverIP, err := s.GetServerIP(server.Server.ID, server.Server.Zone)
	if err != nil {
		return fmt.Errorf("deregistering cloud instance %s of group %q: %w", i.ID, i.CloudInstanceGroup.HumanName, err)
	}

	// We remove the instance's IP from load-balancers
	lbs, err := s.GetClusterLoadBalancers(s.ClusterName(server.Server.Tags))
	if err != nil {
		return fmt.Errorf("deregistering cloud instance %s of group %q: %w", i.ID, i.CloudInstanceGroup.HumanName, err)
	}
	for _, loadBalancer := range lbs {
		backEnds, err := s.lbAPI.ListBackends(&lb.ZonedAPIListBackendsRequest{
			Zone: s.zone,
			LBID: loadBalancer.ID,
		}, scw.WithAllPages())
		if err != nil {
			return fmt.Errorf("deregistering cloud instance %s of group %q: listing load-balancer's back-ends for instance creation: %w", i.ID, i.CloudInstanceGroup.HumanName, err)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the wrapped error status — if 404, the instance is already gone and deregistration is moot.
  2. Verify s.zone matches the server's zone (cluster tags vs Scaleway profile defaults).
  3. Ensure credentials grant servers:read in the project.
  4. Retry after transient API errors.

Example fix

// before: deleting a node then deregistering it
kops delete instance   // server gone -> GetServer 404 -> error
// after: deregister BEFORE deleting the instance
Defensive patterns

Strategy: type-guard

Type guard

func isAlreadyDeleted(err error) bool {
  var respErr *scw.ResponseError
  return errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound
}

Try / catch

if err := cloud.DeregisterInstance(inst); err != nil {
  if isAlreadyDeleted(err) {
    klog.Infof("instance %s already removed; skipping deregister", inst.ID)
    return nil
  }
  return err
}

Prevention

When it happens

Trigger: instanceAPI.GetServer(&instance.GetServerRequest{Zone: s.zone, ServerID: i.ID}) returns an error: server already deleted (404), wrong zone, bad server ID, insufficient permissions, or API/network failure.

Common situations: Deregistering a node that was already terminated out-of-band (404 surfaces as this error); zone mismatch between the kOps config and the server's actual zone; IAM key lacking servers:read.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/6661d8edd2ac7a82. Report an issue: GitHub.