{"record":{"id":"ea1e9f690f1863dc","repo":"kubernetes/kops","slug":"error-listing-akamai-linode-vpcs-w","errorCode":null,"errorMessage":"error listing Akamai (Linode) VPCs: %w","messagePattern":"error listing Akamai \\(Linode\\) VPCs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/linode/resources.go","lineNumber":175,"sourceCode":"\t\tblocks = append(blocks, block)\n\t}\n\tsort.Strings(blocks)\n\n\treturn blocks, nil\n}\n\n// findClusterVPCs finds Akamai (Linode) VPCs with the cluster's deterministic VPC label.\nfunc findClusterVPCs(cloud fi.Cloud, clusterInfo resources.ClusterInfo) ([]linodego.VPC, error) {\n\tc := cloud.(cloudlinode.LinodeCloud)\n\tvpcLabel := cloudlinode.NormalizeLinodeLabel(clusterInfo.Name)\n\tlistOptions, err := cloudlinode.ListOptionsForLabel(vpcLabel)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvpcs, err := c.Client().ListVPCs(context.Background(), listOptions)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing Akamai (Linode) VPCs: %w\", err)\n\t}\n\n\tregion := c.Region()\n\n\tvar clusterVPCs []linodego.VPC\n\tfor _, vpc := range vpcs {\n\t\tif vpc.Label != vpcLabel {\n\t\t\tcontinue\n\t\t}\n\t\tif region != \"\" && vpc.Region != region {\n\t\t\tcontinue\n\t\t}\n\n\t\tclusterVPCs = append(clusterVPCs, vpc)\n\t}\n\n\treturn clusterVPCs, nil\n}","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/linode/resources.go#L157-L193","documentation":"findClusterVPCs in kOps' Akamai (Linode) code (used by listVPCs and listSubnets) wraps failures from linodego's ListVPCs API call. Without the VPC list, kOps cannot identify cluster-owned VPCs or subnets during discovery/deletion.","triggerScenarios":"c.Client().ListVPCs(ctx, listOptions) errors: invalid token, token without VPC read scope, 429 rate limit, or Linode API/network failure.","commonSituations":"Pre-VPC API tokens or old linodego client versions lacking VPC support; rotated LINODE_TOKEN; region/account mismatch between the token and the cluster's VPCs.","solutions":["Verify the Linode API token is valid and has VPC read permissions.","Ensure the linodego/kOps version supports the VPC endpoints (upgrade if the token/account has VPCs but the client is old).","Retry after any rate-limit window if the wrapped error is 429.","Confirm the same Linode account owns the VPCs (region/account check in `linode-cli vpcs list`)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if os.Getenv(\"LINODE_TOKEN\") == \"\" {\n    return errors.New(\"LINODE_TOKEN is not set\")\n}\n// and verify VPC scope: linode-cli vpcs list must succeed","typeGuard":"func isLinodeAuthOrNotFound(err error) bool {\n    var le linodego.Error\n    if !errors.As(err, &le) { return false }\n    return le.Code == 401 || le.Code == 403 || le.Code == 404\n}","tryCatchPattern":"vpcs, err := c.Client().ListVPCs(ctx, listOptions)\nif err != nil {\n    var le linodego.Error\n    if errors.As(err, &le) && le.Code == 429 {\n        return retryWithBackoff(err)\n    }\n    return fmt.Errorf(\"error listing Akamai (Linode) VPCs: %w\", err)\n}","preventionTips":["Use a current linodego/kOps build that supports the VPC API.","Verify VPC read permissions with `linode-cli vpcs list` before kOps operations.","Apply backoff on 429 responses.","Confirm the token's account owns the cluster's VPCs."],"tags":["linode","akamai","vpc","api-listing"],"backgroundTag":"cloud-api-list-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}