kubernetes/kops · error

spotinst: failed to create ocean: %v

Error message

spotinst: failed to create ocean: %v

What it means

kOps failed while asking the Spotinst API to create a new Ocean cluster resource during `kops update cluster`. The underlying Spotinst SDK/HTTP error is wrapped with `%v`, so the real cause (auth, validation, API outage, IAM profile propagation) is in the wrapped message. It is thrown from the create path of `createOrUpdate` after retry handling for a not-ready IAM instance profile has been exhausted.

Source

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

		_, err = cloud.Spotinst().Ocean().Create(context.Background(), oc)
		if err == nil {
			break
		}

		if errs, ok := err.(client.Errors); ok {
			for _, err := range errs {
				if strings.Contains(err.Message, "Invalid IAM Instance Profile name") {
					if attempt > maxAttempts {
						return fmt.Errorf("IAM instance profile not yet created/propagated (original error: %v)", err)
					}

					klog.V(4).Infof("Got an error indicating that the IAM instance profile %q is not ready %q", fi.ValueOf(e.IAMInstanceProfile.Name), err)
					klog.Infof("Waiting for IAM instance profile %q to be ready", fi.ValueOf(e.IAMInstanceProfile.Name))
					goto readyLoop
				}
			}

			return fmt.Errorf("spotinst: failed to create ocean: %v", err)
		}
	}

	return nil
}

func (_ *Ocean) update(cloud awsup.AWSCloud, a, e, changes *Ocean) error {
	klog.V(2).Infof("Updating Ocean %q", *e.Name)

	actual, err := e.find(cloud.Spotinst().Ocean())
	if err != nil {
		klog.Errorf("Unable to resolve Ocean %q, error: %s", *e.Name, err)
		return err
	}

	var changed bool
	ocean := new(aws.Cluster)
	ocean.SetId(actual.ID)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped `%v` message in the error output; it names the actual Spotinst API failure (auth, validation, rate limit).
  2. Verify SPOTINST_TOKEN and SPOTINST_ACCOUNT (or credentials file) are correct and the token has cluster-write permissions.
  3. Re-run `kops update cluster` after a short delay if the cause was an IAM instance profile not yet ready — creation retries are bounded, so a retry usually succeeds once AWS propagates the profile.
  4. Check the Ocean spec fields in the cluster spec (region, image, instance types) against Spotinst API validation rules for your account.

Example fix

// before: kops update cluster fails with 'spotinst: failed to create ocean: 401 unauthorized'
export SPOTINST_TOKEN=stale-token
// after
export SPOTINST_TOKEN=<valid-token>
export SPOTINST_ACCOUNT=<act-xxxx>
kops update cluster --yes
Defensive patterns

Strategy: retry

Validate before calling

// preflight
if os.Getenv("SPOTINST_TOKEN") == "" || os.Getenv("SPOTINST_ACCOUNT") == "" {
    return fmt.Errorf("Spotinst credentials not configured")
}
if err := verifyIAMInstanceProfileReady(profileName); err != nil {
    return fmt.Errorf("IAM instance profile not ready: %w", err)
}

Try / catch

err := runKopsUpdate(ctx)
if err != nil && strings.Contains(err.Error(), "failed to create ocean") {
    // wrapped cause is included; back off and retry for transient/IAM-propagation issues
    return retryWithBackoff(3, 30*time.Second, runKopsUpdate)
}
return err

Prevention

When it happens

Trigger: Calling `kops update cluster` on a Spotinst-backed cluster where the Ocean does not yet exist and `cloud.Spotinst().Ocean().Create(...)` returns an error: invalid Spotinst credentials/token, invalid Ocean spec fields (e.g. image, instance types, region), the IAM instance profile not becoming ready within the readyLoop retries, or the Spotinst API being unreachable/rate-limited.

Common situations: Misconfigured SPOTINST_TOKEN/SPOTINST_ACCOUNT environment values; first cluster creation in a new account; newly created IAM instance profile not yet propagated in AWS so Spotinst rejects it; quota or region-not-enabled issues on the Spotinst account.

Related errors


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