kubernetes/kops · error

DIGITALOCEAN_ACCESS_TOKEN is required

Error message

DIGITALOCEAN_ACCESS_TOKEN is required

What it means

Wraps a failure from AWSCloud.DetachInstance. Before detaching an EC2 instance from its Auto Scaling Group, kOps tags the instance with the ASG name (tagNameDetachedInstance) so the detached instance remains identifiable. If the AWS CreateTags call fails, the underlying SDK error is wrapped in this message.

Source

Thrown at dnsprovider/pkg/dnsprovider/providers/do/dns.go:70

}

// TokenSource implements oauth2.TokenSource
type TokenSource struct {
	AccessToken string
}

// Token returns oauth2.Token
func (t *TokenSource) Token() (*oauth2.Token, error) {
	token := &oauth2.Token{
		AccessToken: t.AccessToken,
	}
	return token, nil
}

func newClient() (*godo.Client, error) {
	accessToken := os.Getenv("DIGITALOCEAN_ACCESS_TOKEN")
	if accessToken == "" {
		return nil, errors.New("DIGITALOCEAN_ACCESS_TOKEN is required")
	}

	tokenSource := &TokenSource{
		AccessToken: accessToken,
	}

	oauthClient := oauth2.NewClient(context.TODO(), tokenSource)
	return godo.NewClient(oauthClient), nil
}

// DNS implements dnsprovider.Interface
type Interface struct {
	client *godo.Client
}

// NewProvider returns an implementation of dnsprovider.Interface
func NewProvider(client *godo.Client) dnsprovider.Interface {
	return &Interface{client: client}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the instance ID still exists with ec2.DescribeInstances before detaching
  2. Check IAM policy grants ec2:CreateTags on the instance resource
  3. Re-run the operation; transient throttling/network errors resolve on retry
  4. Reconcile kops state with `kops rolling-update cluster` to refresh instance info

Example fix

// before
if err := c.CreateTags(id, map[string]string{tagNameDetachedInstance: *asg.AutoScalingGroupName}); err != nil {
	return fmt.Errorf("error tagging instance %q: %v", id, err)
}
// after
if _, err := c.EC2().DescribeInstances(&ec2.DescribeInstancesInput{InstanceIds: []string{id}}); err != nil {
	return fmt.Errorf("instance %q no longer exists, skipping detach: %v", id, err)
}
if err := c.CreateTags(id, map[string]string{tagNameDetachedInstance: *asg.AutoScalingGroupName}); err != nil {
	return fmt.Errorf("error tagging instance %q: %v", id, err)
}
Defensive patterns

Strategy: retry

Validate before calling

_, err := cloud.EC2().DescribeInstances(&ec2.DescribeInstancesInput{InstanceIds: []string{id}})
if err != nil { return fmt.Errorf("instance %q not taggable: %w", id, err) }

Type guard

func instanceExists(out *ec2.DescribeInstancesOutput, id string) bool {
	for _, r := range out.Reservations { for _, i := range r.Instances { if aws.ToString(i.InstanceId) == id && i.State != nil && i.State.Name != ec2.InstanceStateNameTerminated { return true } } }
	return false
}

Try / catch

err := cloud.DetachInstance(ctx, instance)
var throttled *types.ThrottlingException
if errors.As(err, &throttled) { backoffAndRetry(err) } else if strings.Contains(err.Error(), "error tagging instance") { logInvalidInstance(err) }

Prevention

When it happens

Trigger: Calling DetachInstance (rolling-update / instance deletion) where CreateTags fails: instance ID does not exist or was terminated concurrently, invalid instance ID format, credentials lacking ec2:CreateTags, throttling, or a region/network failure.

Common situations: Instance terminated between listing and detaching during a rolling update; IAM policy missing ec2:CreateTags; stale cloud instance state in the kops model; AWS API throttling during large cluster upgrades.

Related errors


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