kubernetes/kops · error

spotinst: failed to update ocean: %v

Error message

spotinst: failed to update ocean: %v

What it means

kOps failed while pushing an updated Ocean cluster spec to the Spotinst API during `kops update cluster`. The Ocean already exists, so the `Ocean().Update` call returned an error and it is wrapped verbatim; the root cause is in the inner message (validation rejection, concurrent modification, auth, API outage).

Source

Thrown at upup/pkg/fi/cloudup/spotinsttasks/ocean.go:1141

		klog.Warningf("Not all changes applied to Ocean %q: %v", *e.Name, changes)
	}

	if !changed {
		klog.V(2).Infof("No changes detected in Ocean %q", *e.Name)
		return nil
	}

	klog.V(2).Infof("Updating Ocean %q (config: %s)", *e.Name, stringutil.Stringify(ocean))

	// Wrap the raw object as an Ocean.
	oc, err := spotinst.NewOcean(cloud.ProviderID(), ocean)
	if err != nil {
		return err
	}

	// Update an existing Ocean.
	if err := cloud.Spotinst().Ocean().Update(context.Background(), oc); err != nil {
		return fmt.Errorf("spotinst: failed to update ocean: %v", err)
	}

	return nil
}

type terraformOcean struct {
	Name                   *string                    `cty:"name"`
	ControllerClusterID    *string                    `cty:"controller_id"`
	Region                 *string                    `cty:"region"`
	InstanceTypesWhitelist []string                   `cty:"whitelist"`
	InstanceTypesBlacklist []string                   `cty:"blacklist"`
	SubnetIDs              []*terraformWriter.Literal `cty:"subnet_ids"`
	AutoScaler             *terraformAutoScaler       `cty:"autoscaler"`
	Tags                   []*terraformKV             `cty:"tags"`

	MinSize         *int64 `cty:"min_size"`
	MaxSize         *int64 `cty:"max_size"`
	DesiredCapacity *int64 `cty:"desired_capacity"`

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped `%v` message for the concrete Spotinst API error code and address that first.
  2. Confirm the Ocean still exists in the Spotinst console; if it was deleted out-of-band, recreate it or remove/recreate the kOps-managed resource.
  3. Avoid immutable field changes (VPC, region) on an existing Ocean — create a new Ocean/cluster instead.
  4. Verify Spotinst credentials and re-run `kops update cluster` if the API was temporarily unavailable.
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: confirm the Ocean still exists before updating
if _, err := spotinstClient.Ocean().Get(ctx, oceanID); err != nil {
    return fmt.Errorf("ocean %s missing; recreate before update: %w", oceanID, err)
}

Try / catch

err := runKopsUpdate(ctx)
if err != nil && strings.Contains(err.Error(), "failed to update ocean") {
    log.Printf("spotinst update rejected: %v", err) // inner message has the API reason
    return err
}

Prevention

When it happens

Trigger: Running `kops update cluster` against an existing Spotinst Ocean when the generated Ocean spec change is rejected: incompatible field change (e.g. region/VPC immutable), Spotinst API 4xx/5xx, expired token, or the Ocean was deleted out-of-band so the update target no longer exists.

Common situations: Changing node instance types, min/max size, or launch specification on a live cluster; stale Spotinst credentials after token rotation; Ocean deleted in the Spotinst console while kOps still tracks it.

Related errors


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