kubernetes/kops · error
error listing Akamai (Linode) SSH keys: %w
Error message
error listing Akamai (Linode) SSH keys: %w
What it means
listSSHKeys in the kOps Linode (Akamai) resource cleanup code enumerates all SSH keys registered with the Linode account via linodego's ListSSHKeys. If that API call fails, the error is wrapped with this message and returned so cluster deletion aborts. It means the Linode API rejected or could not serve the SSH key listing request.
Source
Thrown at pkg/resources/linode/resources.go:200
if vpc.Label != vpcLabel {
continue
}
if region != "" && vpc.Region != region {
continue
}
clusterVPCs = append(clusterVPCs, vpc)
}
return clusterVPCs, nil
}
// listSSHKeys lists Akamai (Linode) SSH keys that were generated for the cluster.
func listSSHKeys(cloud fi.Cloud, clusterInfo resources.ClusterInfo) ([]*resources.Resource, error) {
c := cloud.(cloudlinode.LinodeCloud)
keys, err := c.Client().ListSSHKeys(context.Background(), nil)
if err != nil {
return nil, fmt.Errorf("error listing Akamai (Linode) SSH keys: %w", err)
}
keyLabelPrefix := cloudlinode.NormalizeLinodeLabel("kubernetes."+clusterInfo.Name) + "-"
var resourceTrackers []*resources.Resource
for _, key := range keys {
if !strings.HasPrefix(key.Label, keyLabelPrefix) {
continue
}
resourceTrackers = append(resourceTrackers, &resources.Resource{
Name: key.Label,
ID: strconv.Itoa(key.ID),
Type: resourceTypeSSHKey,
Deleter: deleteSSHKey,
Obj: key,
})
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Verify the Linode API token (LINODE_TOKEN) is valid, unexpired, and has read scopes
- Test connectivity to https://api.linode.com/v4/profile from the host
- Re-run the delete command after transient API errors; the operation is idempotent
- Check Linode status page for API incidents
- Enable linodego debug logging to inspect the raw HTTP response
Example fix
// before
keys, err := c.Client().ListSSHKeys(context.Background(), nil)
if err != nil {
return nil, fmt.Errorf("error listing Akamai (Linode) SSH keys: %w", err)
}
// after
keys, err := c.Client().ListSSHKeys(context.Background(), nil)
if err != nil {
if linodego.ErrCode(err) == 401 {
return nil, fmt.Errorf("error listing Akamai (Linode) SSH keys: check LINODE_TOKEN credentials: %w", err)
}
return nil, fmt.Errorf("error listing Akamai (Linode) SSH keys: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check credentials before running kops delete curl -sS -H "Authorization: Bearer $LINODE_TOKEN" https://api.linode.com/v4/profile | jq .username
Type guard
func isLinodeAuthError(err error) bool { return linodego.ErrCode(err) == 401 || linodego.ErrCode(err) == 403 } Try / catch
keys, err := c.Client().ListSSHKeys(context.Background(), nil)
if err != nil {
if isLinodeAuthError(err) { /* fix token, then retry */ }
return fmt.Errorf("error listing Akamai (Linode) SSH keys: %w", err)
} Prevention
- Keep LINODE_TOKEN valid with read/write scopes before cluster operations
- Check Linode API status page before large deletes
- Avoid running bulk deletes through restrictive proxies
- Retry transient API errors instead of abandoning cleanup
When it happens
Trigger: linodego ListSSHKeys returns a non-nil error: invalid or expired API token, network failure, Linode API 4xx/5xx response, or rate limiting during 'kops delete cluster' discovery of cluster resources.
Common situations: Expired LINODE_TOKEN with insufficient scopes, corporate proxy/firewall blocking api.linode.com, Linode API outage or 429 rate limit while deleting many resources, wrong API endpoint configured.
Related errors
- error deleting Akamai (Linode) SSH key %s(%s): %w
- error listing Akamai (Linode) VPC subnets for VPC %s(%d): %w
- error deleting Akamai (Linode) VPC %s(%s): %w
- error deleting Akamai (Linode) instance %s(%s): %w
- error deleting Akamai (Linode) instance %q: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/0235d19b547cae1e.
Report an issue: GitHub.