kubernetes/kops · critical

unable to parse KubernetesVersion %q: %w

Error message

unable to parse KubernetesVersion %q: %w

What it means

NodeupModelContext.Init (nodeup/pkg/model/context.go:94) pre-parses the Kubernetes version from NodeupConfig.KubernetesVersion using kopsmodel.ParseKubernetesVersion. This error wraps that parse failure and aborts nodeup startup before any model builders run. It indicates the KubernetesVersion string handed to nodeup is empty or not a parseable semver (e.g. missing 'v', extra text, or garbage from a corrupted boot config).

Source

Thrown at nodeup/pkg/model/context.go:94

	// Deprecated: This should be renamed to controlPlaneVersion / nodeVersion;
	// controlPlaneVersion should probably/ideally only be populated on control plane nodes.
	kubernetesVersion *kopsmodel.KubernetesVersion

	bootstrapCerts      map[string]*nodetasks.BootstrapCert
	bootstrapKeypairIDs map[string]string

	// ConfigurationMode determines if we are prewarming an instance or running it live
	ConfigurationMode string
	InstanceID        string
	MachineType       string
}

// Init completes initialization of the object, for example pre-parsing the kubernetes version
func (c *NodeupModelContext) Init() error {
	k8sVersion, err := kopsmodel.ParseKubernetesVersion(c.NodeupConfig.KubernetesVersion)
	if err != nil {
		return fmt.Errorf("unable to parse KubernetesVersion %q: %w", c.NodeupConfig.KubernetesVersion, err)
	}
	c.kubernetesVersion = k8sVersion
	c.bootstrapCerts = map[string]*nodetasks.BootstrapCert{}
	c.bootstrapKeypairIDs = map[string]string{}

	role := c.BootConfig.InstanceGroupRole

	if role.HasControlPlane() {
		c.IsMaster = true
	}

	if role.HasControlPlane() || role.HasAPIServer() {
		c.HasAPIServer = true
	}

	c.usesNoneDNS = c.NodeupConfig.UsesNoneDNS
	c.discoveryService = c.NodeupConfig.DiscoveryService

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the %q value in the error to see exactly what string failed to parse
  2. Verify the cluster spec's kubernetesVersion is a valid semver (e.g. v1.31.0) and re-run kops update/replace to regenerate nodeup config
  3. Ensure the nodeup binary version matches the kops version that rendered the config (avoid version skew)
  4. Re-bootstrap the node or re-render the nodeup config (kops-toolbox nodeup / instance boot) so KubernetesVersion is populated

Example fix

// before (nodeup config)
"kubernetesVersion": "1.31"
// after
"kubernetesVersion": "v1.31.0"
Defensive patterns

Strategy: validation

Validate before calling

// Before booting nodeup, verify the rendered config's version string:
if _, err := kopsmodel.ParseKubernetesVersion(cfg.KubernetesVersion); err != nil {
    return fmt.Errorf("nodeup config has invalid KubernetesVersion %q: %w", cfg.KubernetesVersion, err)
}

Try / catch

if err := modelContext.Init(); err != nil {
    // log full wrapped chain; fail fast, do not retry — config must be fixed
    klog.Fatalf("initializing nodeup model context: %v", err)
}

Prevention

When it happens

Trigger: nodeup Run (or runKubeletBuilder in tests) calls Init() while c.NodeupConfig.KubernetesVersion is empty, malformed (e.g. '1.3x.0', 'v1.31.0-beta-extra'), or missing entirely from the nodeup config rendered by kops-controller / protokube.

Common situations: Running a mismatched or stale nodeup binary against a newer/older cluster config; hand-crafted nodeup configs for testing omitting KubernetesVersion; corrupted protokobe/nodeup config on the node; custom AMI or bootstrap flows passing the wrong version string.

Understand the failure class

Related errors


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