cilium/cilium · error

failed to parse kernel version: %w

Error message

failed to parse kernel version: %w

What it means

After fetching `uname -r` from the agent pod, cilium-cli parses the kernel version with version.ParseKernelVersion. This error means the string returned by uname could not be parsed into a kernel version.

Source

Thrown at cilium-cli/connectivity/check/features.go:225

	}
	result[features.EncryptionPod] = features.Status{
		Enabled: mode != "disabled",
		Mode:    mode,
	}

	return nil
}

func (ct *ConnectivityTest) extractFeaturesFromUname(ctx context.Context, ciliumPod Pod, result features.Set) error {
	stdout, err := ciliumPod.K8sClient.ExecInPod(ctx, ciliumPod.Pod.Namespace, ciliumPod.Pod.Name,
		defaults.AgentContainerName, []string{"uname", "-r"})
	if err != nil {
		return fmt.Errorf("failed to fetch uname -r: %w", err)
	}

	kernelVersion, err := version.ParseKernelVersion(stdout.String())
	if err != nil {
		return fmt.Errorf("failed to parse kernel version: %w", err)
	}

	result[features.RHEL] = features.Status{
		Enabled: versioncheck.MustCompile("<=4.18.0")(kernelVersion),
	}

	return nil
}

func (ct *ConnectivityTest) extractFeaturesFromK8sCluster(ctx context.Context, result features.Set) {
	flavor := ct.client.AutodetectFlavor(ctx)

	result[features.Flavor] = features.Status{
		Enabled: flavor.Kind.String() != "invalid",
		Mode:    strings.ToLower(flavor.Kind.String()),
	}
}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Run `kubectl exec ... -- uname -r` and inspect the exact string
  2. Compare with version.ParseKernelVersion's accepted format; account for suffixes
  3. Ensure the agent container actually contains uname and PATH resolves it
  4. Retry — transient exec errors can yield empty stdout
  5. If the kernel string is truly exotic, file/report upstream to extend the parser

Example fix

// before: parse whatever came back
kernelVersion, err := version.ParseKernelVersion(stdout.String())
if err != nil { return fmt.Errorf("failed to parse kernel version: %w", err) }
// after: trim and sanity-check before parsing
release := strings.TrimSpace(stdout.String())
if release == "" {
	return fmt.Errorf("empty uname -r output")
}
kernelVersion, err := version.ParseKernelVersion(release)
if err != nil { return fmt.Errorf("failed to parse kernel version %q: %w", release, err) }
Defensive patterns

Strategy: try-catch

Validate before calling

out, err := k8sClient.ExecInPod(ctx, ns, pod, "cilium-agent", []string{"uname", "-r"})
if err == nil {
	release := strings.TrimSpace(out.String())
	if release == "" || strings.Contains(release, " ") {
		log.Warnf("suspicious uname -r output: %q", release)
	}
}

Type guard

func looksLikeKernelRelease(s string) bool {
	parts := strings.Split(strings.TrimSpace(s), ".")
	return len(parts) >= 2 && isNumeric(parts[0]) && isNumeric(strings.SplitN(parts[1], "-", 2)[0])
}

Try / catch

if err := ct.extractFeaturesFromUname(ctx, ciliumPod, result); err != nil {
	if strings.Contains(err.Error(), "failed to parse kernel version") {
		log.Warnf("kernel version unparsable; skipping RHEL detection: %v", err)
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: version.ParseKernelVersion(stdout.String()) fails on unexpected uname output, e.g. empty output, 'uname: command not found', kernel strings with unusual suffixes/characters the parser doesn't handle.

Common situations: Exec returned an error message on stdout instead of the release string; exotic/custom kernels (e.g. '-coreos', aarch64 with odd formatting, CONTAINER-optimized kernels) with non-standard release strings; minimal agent images lacking uname.

Understand the failure class

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/a11b77ddddf6babf. Report an issue: GitHub.