kubernetes/kops · error

error listing Akamai (Linode) volumes: %w

Error message

error listing Akamai (Linode) volumes: %w

What it means

Fires in listVolumes when the Linode API ListVolumes call fails while discovering cluster-tagged block storage volumes during resource discovery/teardown — an API, credentials, or network failure, not an absence of volumes.

Source

Thrown at pkg/resources/linode/resources.go:120

			Obj:     instance,
		})
	}

	return resourceTrackers, nil
}

// listVolumes lists Akamai (Linode) block storage volumes owned by the cluster.
func listVolumes(cloud fi.Cloud, clusterInfo resources.ClusterInfo) ([]*resources.Resource, error) {
	c := cloud.(cloudlinode.LinodeCloud)
	clusterTag := cloudlinode.NormalizeLinodeLabel(clusterInfo.Name)
	listOptions, err := cloudlinode.ListOptionsForTags(fmt.Sprintf("%s:%s", cloudlinode.TagKubernetesClusterName, clusterTag))
	if err != nil {
		return nil, err
	}

	volumes, err := c.Client().ListVolumes(context.Background(), listOptions)
	if err != nil {
		return nil, fmt.Errorf("error listing Akamai (Linode) volumes: %w", err)
	}

	resourceTrackers := make([]*resources.Resource, 0, len(volumes))
	for _, volume := range volumes {
		resourceTracker := &resources.Resource{
			Name:    volume.Label,
			ID:      strconv.Itoa(volume.ID),
			Type:    resourceTypeVolume,
			Deleter: deleteVolume,
			Obj:     volume,
		}
		if volume.LinodeID != nil {
			resourceTracker.Blocked = []string{resourceTypeInstance + ":" + strconv.Itoa(*volume.LinodeID)}
		}
		resourceTrackers = append(resourceTrackers, resourceTracker)
	}

	return resourceTrackers, nil

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the Linode API token and its scopes
  2. Retry after transient API errors or rate limiting
  3. Verify the cluster label normalization matches the volumes' tags
Defensive patterns

Strategy: retry

Validate before calling

if os.Getenv("LINODE_TOKEN") == "" {
    return errors.New("LINODE_TOKEN is not set")
}

Type guard

func isLinodeRateLimit(err error) bool {
    var le linodego.Error
    return errors.As(err, &le) && le.Code == 429
}

Try / catch

volumes, err := c.Client().ListVolumes(ctx, listOptions)
if err != nil {
    if isLinodeRateLimit(err) {
        time.Sleep(retryAfter)
        volumes, err = c.Client().ListVolumes(ctx, listOptions)
    }
    if err != nil {
        return fmt.Errorf("error listing Akamai (Linode) volumes: %w", err)
    }
}

Prevention

When it happens

Trigger: c.Client().ListVolumes(ctx, listOptions) errors: bad API token, insufficient scopes, rate limiting, network error, or region filter mismatch producing an API-side rejection.

Common situations: Expired LINODE_TOKEN during teardown; Linode API incident; token restricted to read-only scopes while listing works but downstream operations fail.

Related errors


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