kubernetes/kops · error

digital ocean cloud provider does not support surging

Error message

digital ocean cloud provider does not support surging

What it means

DetachInstance is intentionally unimplemented in the DigitalOcean cloud provider. kOps calls it when performing 'surging' rolling updates (adding a new node before detaching/removing the old one); the DO provider only supports in-place replacement, so it always returns this error. It is a hard capability limitation, not a transient fault.

Source

Thrown at upup/pkg/fi/cloudup/do/cloud.go:177

		}

		time.Sleep(time.Minute * 1)
	}

	_, err = c.Client.Droplets.Delete(context.TODO(), dropletID)
	if err != nil {
		return fmt.Errorf("error stopping instance %d: %v", dropletID, err)
	}

	klog.V(8).Infof("deleted droplet instance %d", dropletID)

	return nil
}

// DetachInstance is not implemented yet. It needs to cause a cloud instance to no longer be counted against the group's size limits.
func (c *doCloudImplementation) DetachInstance(i *cloudinstances.CloudInstance) error {
	klog.V(8).Info("digitalocean cloud provider DetachInstance not implemented yet")
	return fmt.Errorf("digital ocean cloud provider does not support surging")
}

// ProviderID returns the kops api identifier for DigitalOcean cloud provider
func (c *doCloudImplementation) ProviderID() kops.CloudProviderID {
	return kops.CloudProviderDO
}

// Region returns the DO region we will target
func (c *doCloudImplementation) Region() string {
	return c.region
}

func (c *doCloudImplementation) DNS() (dnsprovider.Interface, error) {
	provider, err := dnsprovider.GetDnsProvider(dns.ProviderName, nil)
	if err != nil {
		return nil, fmt.Errorf("error building DNS provider: %v", err)
	}
	return provider, nil

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Use non-surging rolling updates on DigitalOcean (default in-place replace, e.g. `--master-interval`/`--node-interval` without surge options).
  2. Set the instance group's rolling-update policy to not surge (avoid CloudProviderBatching/surging options that trigger DetachInstance).
  3. If surging is required, run the workload on a provider that implements it (AWS, GCE) or implement DetachInstance for DO upstream.
  4. Work around manually: scale the group up, then down, outside of the surging code path.

Example fix

// before (kops CLI)
kops rolling-update cluster my.cluster --instance-group nodes --surge
// after
kops rolling-update cluster my.cluster --instance-group nodes  # sequential, non-surging
Defensive patterns

Strategy: fallback

Validate before calling

// check provider capability before choosing a surging update strategy
if cluster.Spec.CloudProvider == kops.CloudProviderID("digitalocean") {
    // do not enable surging; DetachInstance is unsupported
}

Try / catch

if err := cloud.DetachInstance(ci); err != nil {
    if strings.Contains(err.Error(), "does not support surging") {
        return rollingUpdateInPlace(inst) // fallback strategy
    }
    return err
}

Prevention

When it happens

Trigger: Any kOps rolling-update on a DigitalOcean cluster that runs with surging enabled (e.g. `kops rolling-update cluster --instance-group X` where the group is configured to surge / the update policy builds a new instance before detaching the old).

Common situations: Users switching rolling-update strategy on DO clusters expecting AWS-like detach/attach behavior; automation that calls cloud provider DetachInstance generically across clouds.

Related errors


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