{"record":{"id":"e547ada2d8a28f2b","repo":"kubernetes/kops","slug":"error-listing-akamai-linode-volumes-w-e547ad","errorCode":null,"errorMessage":"error listing Akamai (Linode) volumes: %w","messagePattern":"error listing Akamai \\(Linode\\) volumes: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/linodetasks/volume.go","lineNumber":61,"sourceCode":"func (v *Volume) CompareWithID() *string {\n\treturn v.Name\n}\n\nfunc (v *Volume) Find(c *fi.CloudupContext) (*Volume, error) {\n\tcloud := c.T.Cloud.(linode.LinodeCloud)\n\tname := fi.ValueOf(v.Name)\n\tif name == \"\" {\n\t\treturn nil, fmt.Errorf(\"Volume.Name is required\")\n\t}\n\tlabel := truncate.TruncateString(linode.NormalizeLinodeLabel(name), truncate.TruncateStringOptions{MaxLength: 32})\n\tlistOptions, err := linode.ListOptionsForLabel(label)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvolumes, err := cloud.Client().ListVolumes(c.Context(), listOptions)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing Akamai (Linode) volumes: %w\", err)\n\t}\n\n\tif len(volumes) == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Name is unique, so we should only have one match\n\tmatched := volumes[0]\n\n\tactual := &Volume{\n\t\tID:        new(matched.ID),\n\t\tName:      new(name),\n\t\tLifecycle: v.Lifecycle,\n\t\tRegion:    new(matched.Region),\n\t\tSizeGB:    new(matched.Size),\n\t\tTags:      matched.Tags,\n\t}\n\tv.ID = actual.ID","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/linodetasks/volume.go#L43-L79","documentation":"Volume.Find wraps any error from linodego's ListVolumes call with this message. It means the Linode API list volumes request failed while trying to find a matching volume by label. The underlying cause is preserved via %w.","triggerScenarios":"cloud.Client().ListVolumes(c.Context(), listOptions) returns an error during Volume.Find, e.g. network failure, bad API token, or malformed label list options.","commonSituations":"Expired or scope-limited Linode API token; Linode API outage or rate limiting; network/proxy issues from the CI runner; ListOptionsForLabel produced options the API rejects.","solutions":["Unwrap the error to read the Linode API status (401/403 -> fix token scopes; 429 -> back off and retry)","Verify LINODE_TOKEN / API credentials are valid and have volumes:read access","Retry the kops update if the cause is a transient 5xx or network error","Check Linode status page for an ongoing API incident"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, err := kops.UpdateCluster(ctx, opts)\nif err != nil && strings.Contains(err.Error(), \"error listing Akamai (Linode) volumes\") {\n  var apiErr *linodego.Error\n  if errors.As(err, &apiErr) && (apiErr.Code == 429 || apiErr.Code >= 500) {\n    // retry with exponential backoff\n  } else if errors.As(err, &apiErr) && (apiErr.Code == 401 || apiErr.Code == 403) {\n    // refresh LINODE_TOKEN / fix scopes\n  }\n}","preventionTips":["Verify LINODE_TOKEN validity and volumes:read scope before running kops","Retry transient list failures with backoff instead of failing the pipeline","Monitor Linode API status during CI runs","Use a stable network path (no aggressive proxy) for API calls from CI runners"],"tags":["linode","volume","api-error","listing"],"backgroundTag":"linode-api-call-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}