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

  1. 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
  2. Check the account's volume size quota and request an increase via the Linode/Akamai console if the requested SizeGB exceeds it
  3. Verify SizeGB is larger than current size (shrinks are rejected by CheckChanges) and within the region maximum (10240 GB)
  4. Confirm the API token has volumes:read_write scope and has not expired
  5. 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

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


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/2a6a66dfbb5fa559. Report an issue: GitHub.