kubernetes/kops · error
error resizing Akamai (Linode) volume %q: %w
Error message
error resizing Akamai (Linode) volume %q: %w
What it means
This error wraps a failure from the Linode API call ResizeVolume when kOps' RenderLinode tries to grow an existing block-storage volume to the size declared in the cluster spec. It is only reached when the volume already exists (actual != nil) and the diff contains a SizeGB change. The underlying linodego error (auth, quota, invalid size, volume attached to a powered-on instance, etc.) is preserved via %w.
Source
Thrown at upup/pkg/fi/cloudup/linodetasks/volume.go:132
if expected.SizeGB == nil {
return fi.RequiredField("SizeGB")
}
if fi.ValueOf(expected.SizeGB) < 10 {
return fmt.Errorf("SizeGB must be at least 10 GB")
}
}
return nil
}
func (*Volume) RenderLinode(t *linode.APITarget, actual, expected, changes *Volume) error {
if actual != nil {
expected.ID = actual.ID
if changes.SizeGB == nil {
return nil
}
if err := t.Cloud.Client().ResizeVolume(context.Background(), fi.ValueOf(actual.ID), linodego.VolumeResizeOptions{Size: fi.ValueOf(expected.SizeGB)}); err != nil {
return fmt.Errorf("error resizing Akamai (Linode) volume %q: %w", fi.ValueOf(actual.Name), err)
}
klog.V(2).Infof("Resized Akamai (Linode) volume %q (id=%d) to %d GB", fi.ValueOf(actual.Name), fi.ValueOf(actual.ID), fi.ValueOf(expected.SizeGB))
return nil
}
name := fi.ValueOf(expected.Name)
label := truncate.TruncateString(linode.NormalizeLinodeLabel(name), truncate.TruncateStringOptions{MaxLength: 32})
created, err := t.Cloud.Client().CreateVolume(context.Background(), linodego.VolumeCreateOptions{
Label: label,
Region: fi.ValueOf(expected.Region),
Size: fi.ValueOf(expected.SizeGB),
Tags: expected.Tags,
})
if err != nil {
return fmt.Errorf("error creating Akamai (Linode) volume %q: %w", name, err)
}
expected.ID = new(created.ID)View on GitHub (pinned to 4c8573c808)
Solutions
- Detach/unattach the volume or shut down the Linode instance it is attached to (Linode cannot resize an attached volume while the instance is running), then re-run the update
- Check the account's volume size quota and request an increase via the Linode/Akamai console if the requested SizeGB exceeds it
- Verify SizeGB is larger than current size (shrinks are rejected by CheckChanges) and within the region maximum (10240 GB)
- Confirm the API token has volumes:read_write scope and has not expired
- Retry the kops update if the failure was a transient 5xx; the resize is idempotent for an unchanged spec
Example fix
// before: resize attempted while volume attached to a running instance
if err := t.Cloud.Client().ResizeVolume(ctx, id, linodego.VolumeResizeOptions{Size: newSize}); err != nil { ... }
// after: shut down / detach first, or pre-check via instance state
inst, _ := client.GetInstance(ctx, attachedInstanceID)
if inst.Status != linodego.InstanceOffline { return fmt.Errorf("stop instance %d before resizing volume", attachedInstanceID) }
return t.Cloud.Client().ResizeVolume(ctx, id, linodego.VolumeResizeOptions{Size: newSize}) Defensive patterns
Strategy: validation
Validate before calling
// Caller-side guard in cluster spec / before running update:
func validateVolumeResize(current, desired int, attachedInstanceID *int, instanceRunning bool) error {
if desired <= current {
return fmt.Errorf("desired size %d GB must be greater than current %d GB (shrinks unsupported)", desired, current)
}
if desired > 10240 {
return fmt.Errorf("desired size %d GB exceeds Linode volume max of 10240 GB", desired)
}
if attachedInstanceID != nil && instanceRunning {
return fmt.Errorf("volume attached to running instance %d; stop/detach before resizing", *attachedInstanceID)
}
return nil
} Type guard
func isVolumeResizeConflict(err error) bool {
var apiErr *linodego.Error
if errors.As(err, &apiErr) {
return apiErr.Code == 400 && strings.Contains(strings.ToLower(apiErr.Message), "attach")
}
return false
} Try / catch
if err := run(); err != nil {
var apiErr *linodego.Error
if errors.As(err, &apiErr) && apiErr.Code == 429 {
// back off and retry once
}
return fmt.Errorf("volume resize failed: %w", err)
} Prevention
- Never decrease SizeGB in the cluster spec; only grow
- Stop or detach the volume's instance before planned resizes
- Track account volume quota in the Linode console before large changes
- Keep SizeGB within the 10-10240 GB range
- Use a token with volumes:read_write scope and rotate before expiry
When it happens
Trigger: An existing Linode Volume is found by Find(), the cluster spec sets a larger SizeGB, and the ResizeVolume API call fails - e.g. the volume is currently attached to a running Linode instance, the requested size exceeds the account volume-size quota, or the API returns 4xx/5xx (invalid token, size above region max of 10240 GB, transient server error).
Common situations: Users edit instanceGroup/cluster yaml to enlarge persistent storage during an upgrade or 'kops update' run while the volume is attached to a booted node; accounts hitting the default volume quota; typos in cluster spec producing a size larger than the region limit.
Related errors
- error creating Akamai (Linode) volume %q: %w
- error creating Akamai (Linode) VPC %q: %w
- adding encryptionconfig secret: %v
- updating encryptionconfig secret: %v
- unable to check for instanceGroup: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/2a6a66dfbb5fa559.
Report an issue: GitHub.