kubernetes/kops · error

invalid instance id %q: %w

Error message

invalid instance id %q: %w

What it means

parseInstanceIDFromProviderID converts the trailing providerID segment into a numeric Linode instance ID with strconv.Atoi. This error wraps the parse failure when that segment is not a decimal integer, e.g. 'linode://abc' or a URL containing extra non-numeric data.

Source

Thrown at pkg/nodeidentity/linode/identify.go:143

	if !strings.HasPrefix(providerID, providerIDPrefix) {
		return 0, "", fmt.Errorf("missing prefix %q", providerIDPrefix)
	}

	raw := strings.TrimPrefix(providerID, providerIDPrefix)
	raw = strings.Trim(raw, "/")
	if raw == "" {
		return 0, "", fmt.Errorf("missing instance id")
	}

	parts := strings.Split(raw, "/")
	instanceID := parts[len(parts)-1]
	if instanceID == "" {
		return 0, "", fmt.Errorf("missing instance id")
	}

	linodeID, err := strconv.Atoi(instanceID)
	if err != nil {
		return 0, "", fmt.Errorf("invalid instance id %q: %w", instanceID, err)
	}

	return linodeID, instanceID, nil
}

// isExpectedInstanceStatus returns true if the instance is in a state where it can be identified.
func isExpectedInstanceStatus(status linodego.InstanceStatus) bool {
	switch status {
	case linodego.InstanceRunning, linodego.InstanceBooting, linodego.InstanceProvisioning:
		return true
	default:
		return false
	}
}

// buildLabelsFromTags converts Akamai (Linode) instance tags into Kubernetes node labels.
// It handles role tags (kops.k8s.io/instance-role) and direct label tags (kops.k8s.io/* and node-role.kubernetes.io/*).
func buildLabelsFromTags(tags []string) map[string]string {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the node's providerID value and correct it to the format 'linode://<numeric-instance-id>'
  2. Confirm the installed Linode cloud-controller-manager version emits numeric instance IDs in providerID
  3. Trim or normalize the providerID string (strip whitespace, extra path segments) before node identification

Example fix

// before
node.Spec.ProviderID = "linode://i-abc123"
// after
node.Spec.ProviderID = "linode://12345678"
Defensive patterns

Strategy: validation

Validate before calling

pid := node.Spec.ProviderID
id := pid[strings.LastIndex(pid, "/")+1:]
if _, err := strconv.Atoi(id); err != nil {
    return fmt.Errorf("providerID %q does not end in a numeric linode instance id", pid)
}

Type guard

func isNumericLinodeProviderID(pid string) bool {
    const prefix = "linode://"
    if !strings.HasPrefix(pid, prefix) {
        return false
    }
    _, err := strconv.Atoi(strings.TrimPrefix(pid, prefix))
    return err == nil
}

Prevention

When it happens

Trigger: providerID's last '/'-separated segment fails Atoi: non-numeric text ('linode://my-server'), embedded whitespace, or a multi-segment tail where the wrong segment is picked (e.g. 'linode://us-east/instance/abc').

Common situations: Custom or legacy providerID formats that don't match the expected 'linode://<numeric-id>' scheme, or providerIDs produced by a different tool/version of the Linode CCM.

Related errors


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