{"record":{"id":"748c1545d481029e","repo":"kubernetes/kops","slug":"error-deleting-akamai-linode-subnet-s-s-w","errorCode":null,"errorMessage":"error deleting Akamai (Linode) subnet %s(%s): %w","messagePattern":"error deleting Akamai \\(Linode\\) subnet (.+?)\\((.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/linode/resources.go","lineNumber":323,"sourceCode":"\t\treturn fmt.Errorf(\"error deleting Akamai (Linode) VPC %s(%s): %w\", tracker.Name, tracker.ID, err)\n\t}\n\n\treturn nil\n}\n\n// deleteSubnet deletes an Akamai (Linode) VPC subnet.\nfunc deleteSubnet(vpcID int, cloud fi.Cloud, tracker *resources.Resource) error {\n\tc := cloud.(cloudlinode.LinodeCloud)\n\tsubnetID, err := parseTrackerIntID(tracker)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := c.Client().DeleteVPCSubnet(context.Background(), vpcID, subnetID); err != nil {\n\t\tif linodego.IsNotFound(err) {\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"error deleting Akamai (Linode) subnet %s(%s): %w\", tracker.Name, tracker.ID, err)\n\t}\n\n\treturn nil\n}\n\n// deleteInstance deletes an Akamai (Linode) instance.\nfunc deleteInstance(cloud fi.Cloud, tracker *resources.Resource) error {\n\tc := cloud.(cloudlinode.LinodeCloud)\n\tinstanceID, err := parseTrackerIntID(tracker)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := c.Client().DeleteInstance(context.Background(), instanceID); err != nil {\n\t\tif linodego.IsNotFound(err) {\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"error deleting Akamai (Linode) instance %s(%s): %w\", tracker.Name, tracker.ID, err)","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/linode/resources.go#L305-L341","documentation":"deleteSubnet removes a subnet from a Linode VPC via DeleteVPCSubnet. Failures other than not-found are wrapped with the subnet name and ID. Not-found is treated as success, so this signals a genuine API failure deleting the subnet.","triggerScenarios":"c.Client().DeleteVPCSubnet(ctx, vpcID, subnetID) fails: token lacks write scopes, subnet still in use by compute instances, invalid vpcID/subnetID, network error, or rate limit.","commonSituations":"Subnets with attached Linodes cannot be deleted; interrupted previous delete left partial state; read-only token; concurrent operators modifying the VPC.","solutions":["Detach/delete all instances using the subnet before deleting it","Retry 'kops delete cluster' — deletion is idempotent","Use a token with write scopes","Verify vpcID/subnetID still exist in Linode Cloud Manager","Check the wrapped Linode API error for the status code"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Confirm subnet exists and has no attached Linodes before deletion\nsubnets, _ := c.Client().ListVPCSubnets(ctx, vpcID, nil)\nfor _, s := range subnets { if s.ID == subnetID { /* exists */ } }","typeGuard":"func isSubnetInUse(err error) bool { c := linodego.ErrCode(err); return c == 400 || c == 409 }","tryCatchPattern":"if err := c.Client().DeleteVPCSubnet(ctx, vpcID, subnetID); err != nil {\n\tif linodego.IsNotFound(err) { return nil }\n\tif isSubnetInUse(err) { /* delete attached instances first */ }\n\treturn fmt.Errorf(\"error deleting Akamai (Linode) subnet %s(%s): %w\", tracker.Name, tracker.ID, err)\n}","preventionTips":["Delete all instances using the subnet before the subnet itself","Rely on kops' dependency-ordered cleanup","Retry after partial failures","Verify IDs against Cloud Manager when errors persist"],"tags":["linode","akamai","vpc","subnet","delete"],"backgroundTag":"linode-api-request-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"}