kubernetes/kops · error

evictionHard: %w

Error message

evictionHard: %w

What it means

parseKeyValueList converts the kops CSV-style EvictionHard string (e.g. "memory.available<100Mi,nodefs.available<10%") into the map[string]string the kubelet config requires, splitting each pair on '<'. If any comma-separated entry lacks the '<' separator, parsing fails and the error is wrapped as "evictionHard: %w" with the detail "invalid key/value pair ...".

Source

Thrown at nodeup/pkg/model/kubelet.go:388

	}

	// EventQPS is the legacy kops field; EventRecordQPS is the newer alias
	// matching the kubelet config field name. Preserve historical precedence
	// where EventQPS overrides EventRecordQPS when both are set.
	if kubeletConfig.EventQPS != nil {
		cc.EventRecordQPS = kubeletConfig.EventQPS
	}

	if b.NodeupConfig.ContainerdConfig.Address == nil {
		cc.ContainerRuntimeEndpoint = "unix:///run/containerd/containerd.sock"
	} else {
		cc.ContainerRuntimeEndpoint = "unix://" + fi.ValueOf(b.NodeupConfig.ContainerdConfig.Address)
	}

	if kubeletConfig.EvictionHard != nil {
		evictionHard, err := parseKeyValueList(*kubeletConfig.EvictionHard, "<")
		if err != nil {
			return nil, fmt.Errorf("evictionHard: %w", err)
		}
		cc.EvictionHard = evictionHard
	}
	evictionSoft, err := parseKeyValueList(kubeletConfig.EvictionSoft, "<")
	if err != nil {
		return nil, fmt.Errorf("evictionSoft: %w", err)
	}
	cc.EvictionSoft = evictionSoft
	evictionSoftGracePeriod, err := parseKeyValueList(kubeletConfig.EvictionSoftGracePeriod, "=")
	if err != nil {
		return nil, fmt.Errorf("evictionSoftGracePeriod: %w", err)
	}
	cc.EvictionSoftGracePeriod = evictionSoftGracePeriod
	evictionMinimumReclaim, err := parseKeyValueList(kubeletConfig.EvictionMinimumReclaim, "=")
	if err != nil {
		return nil, fmt.Errorf("evictionMinimumReclaim: %w", err)
	}
	cc.EvictionMinimumReclaim = evictionMinimumReclaim

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped message for the offending pair %q and add the '<' separator (e.g. memory.available<100Mi)
  2. Run kops edit cluster and fix spec.kubelet.evictionHard entries
  3. Remember each pair must be key<value, comma-separated, no trailing commas
  4. Re-run kops update cluster / nodeup after fixing

Example fix

// before
kubelet:
  evictionHard: "memory.available=100Mi"
// after
kubelet:
  evictionHard: "memory.available<100Mi,nodefs.available<10%"
Defensive patterns

Strategy: validation

Validate before calling

func validEvictionHard(s string) bool {
    if s == "" { return true }
    for _, kv := range strings.Split(s, ",") {
        if !strings.Contains(kv, "<") { return false }
    }
    return true
}
// assert validEvictionHard(cluster.Spec.Kubelet.EvictionHard) before update

Try / catch

cfg, err := kubeletConfiguration(...)
if err != nil && strings.Contains(err.Error(), "evictionHard:") {
    return fmt.Errorf("fix spec.kubelet.evictionHard: each pair needs '<': %w", err)
}

Prevention

When it happens

Trigger: kubeletConfiguration -> parseKeyValueList(*kubeletConfig.EvictionHard, "<") returns an error because an entry in spec.kubelet.evictionHard contains no '<' character.

Common situations: Typo in the cluster spec such as "memory.available=100Mi" (used '=' instead of '<'); a stray comma producing an empty or separator-less entry; copying evictionSoft syntax (which uses '<') but writing grace-period style '=' pairs into evictionHard.

Related errors


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