kubernetes/kops · error

error querying DigitalOcean droplet ID

Error message

error querying DigitalOcean droplet ID: %w

What it means

Wraps a failure of the DigitalOcean metadata query during kubelet builder setup on a DO droplet: the node's provider ID cannot be determined because the droplet metadata service did not answer correctly.

Solutions

  1. Ensure the node can reach the DO metadata service at 169.254.169.254.
  2. Run nodeup on an actual droplet; it cannot resolve droplet ID elsewhere.
  3. Retry after transient metadata failures.
  4. Check the wrapped error (uses %w) with errors.Is/As for network vs parse cause.
Defensive patterns

Strategy: retry

Validate before calling

// before nodeup on a droplet: probe DO metadata
body, err := fetch("http://169.254.169.254/metadata/v1/id")
if err != nil || body == "" {
    return errors.New("droplet metadata unavailable")
}

Try / catch

err := runNodeup(ctx)
if err != nil {
    var doErr error
    if errors.As(err, &doErr) && strings.Contains(err.Error(), "droplet ID") {
        // error is wrapped with %w; inspect cause and retry on timeouts
        return retryAfter(30*time.Second, err)
    }
    return err
}

Prevention

When it happens

Trigger: GetDropletID fails — the DigitalOcean metadata endpoint (169.254.169.254/metadata) is unreachable, times out, or returns a response without a droplet id.

Common situations: Metadata service blocked by firewall, running nodeup outside a real droplet (e.g. in a container/Packer build), transient DO metadata outage.

Related errors


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

Appendix: source

Thrown at nodeup/pkg/model/kubelet.go:140

			}
			metadata := imds.NewFromConfig(config)
			instanceIdentity, err := metadata.GetInstanceIdentityDocument(ctx, &imds.GetInstanceIdentityDocumentInput{})
			if err != nil {
				return err
			}
			providerID = fmt.Sprintf("aws:///%s/%s", instanceIdentity.AvailabilityZone, instanceIdentity.InstanceID)
		} else if b.CloudProvider() == kops.CloudProviderAzure {
			metadata, err := azuremetadata.QueryComputeInstanceMetadata(ctx)
			if err != nil {
				return fmt.Errorf("error querying Azure instance metadata: %v", err)
			}
			providerID = "azure://" + metadata.ResourceID
		} else if b.CloudProvider() == kops.CloudProviderDO {
			// The DO CCM resolves nodes by provider ID; its name-based fallback does not match
			// our IP-based node names.
			dropletID, err := dometadata.GetDropletID()
			if err != nil {
				return fmt.Errorf("error querying DigitalOcean droplet ID: %w", err)
			}
			providerID = "digitalocean://" + dropletID
		}

		t, err := b.buildKubeletComponentConfig(kubeletConfig, providerID)
		if err != nil {
			return err
		}

		c.AddTask(t)
	}

	{
		t, err := b.buildSystemdEnvironmentFile(c.Context(), kubeletConfig)
		if err != nil {
			return err
		}
		c.AddTask(t)

View on GitHub (pinned to 4c8573c808)