cilium/cilium · error

unable to parse cilium version on pod %q: %w

Error message

unable to parse cilium version on pod %q: %w

What it means

Returned by `Client.GetCiliumVersion` when the exec succeeds but the output cannot be parsed by `semver.Parse` after stripping the proprietary `-releaseX` suffix. It means `cilium version -o jsonpath={$.Daemon.Version}` produced something that is not a semantic version (empty output, error text, or a non-conforming version string).

Source

Thrown at cilium-cli/k8s/client.go:1096

// GetCiliumVersion returns a semver.Version representing the version of cilium
// running in the cilium-agent pod
func (c *Client) GetCiliumVersion(ctx context.Context, p *corev1.Pod) (*semver.Version, error) {
	o, _, err := c.ExecInPodWithStderr(
		ctx,
		p.Namespace,
		p.Name,
		defaults.AgentContainerName,
		[]string{"cilium", "version", "-o", "jsonpath={$.Daemon.Version}"},
	)
	if err != nil {
		return nil, fmt.Errorf("unable to fetch cilium version on pod %q: %w", p.Name, err)
	}

	v, _, _ := strings.Cut(strings.TrimSpace(o.String()), "-") // strips proprietary -releaseX suffix
	podVersion, err := semver.Parse(v)
	if err != nil {
		return nil, fmt.Errorf("unable to parse cilium version on pod %q: %w", p.Name, err)
	}

	return &podVersion, nil
}

func (c *Client) GetRunningCiliumVersion(ciliumHelmReleaseName string) (string, error) {
	m, err := action.NewGetMetadata(c.HelmActionConfig).Run(ciliumHelmReleaseName)
	if err != nil {
		return "", err
	}
	return m.Version, nil
}

func (c *Client) ListCiliumLocalRedirectPolicies(ctx context.Context, namespace string, opts metav1.ListOptions) (*ciliumv2.CiliumLocalRedirectPolicyList, error) {
	return c.CiliumClientset.CiliumV2().CiliumLocalRedirectPolicies(namespace).List(ctx, opts)
}

func (c *Client) GetServerVersion() (*semver.Version, error) {

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Run `kubectl exec <pod> -c cilium-agent -- cilium version -o jsonpath={$.Daemon.Version}` to see the raw output and fix the build/tag
  2. Ensure the image is an official cilium release with a valid semver tag
  3. Check for wrapper scripts or sidecar logs polluting stdout before the jsonpath output
  4. Inspect the wrapped `%w` semver error to see exactly what string failed to parse

Example fix

// before
v, _, _ := strings.Cut(strings.TrimSpace(o.String()), "-")
podVersion, err := semver.Parse(v)
// after
raw := strings.TrimSpace(o.String())
if raw == "" {
    return nil, fmt.Errorf("empty cilium version output from pod %q", p.Name)
}
v, _, _ := strings.Cut(raw, "-")
if !semver.IsValid(v) { // guard against non-semver custom builds
    return nil, fmt.Errorf("cilium pod %q reports non-semver version %q", p.Name, v)
}
podVersion, err := semver.Parse(v)
Defensive patterns

Strategy: validation

Validate before calling

out, _, err := client.ExecInPodWithStderr(ctx, ns, podName, "cilium-agent",
    []string{"cilium", "version", "-o", "jsonpath={$.Daemon.Version}"})
if err != nil { return err }
v := strings.TrimSpace(out.String())
if _, perr := semver.Parse(strings.Cut(v, "-")[0]); perr != nil {
    return fmt.Errorf("pod reports non-semver cilium version %q", v)
}

Type guard

func isSemver(s string) bool {
    _, err := semver.Parse(strings.TrimSpace(strings.Cut(s, "-")[0]))
    return err == nil
}

Try / catch

ver, err := client.GetCiliumVersion(ctx, pod)
if err != nil && strings.Contains(err.Error(), "unable to parse cilium version") {
    // agent output not semver: fall back to Helm release version or skip version gate
    return client.GetRunningCiliumVersion(releaseName)
}

Prevention

When it happens

Trigger: Calling `GetCiliumVersion` where the agent returns empty/garbage output (exec output truncated), the daemon field is missing from the JSON output, or the version string lacks MAJOR.MINOR.PATCH components (custom/patched cilium builds, debug builds).

Common situations: Custom cilium builds with versions like `1.14-custom` or no version; agent binary replaced/older than the pod image; jsonpath output empty because an incompatible cilium version lacks the `$.Daemon.Version` field; locale/CI logging wrapper prepending text to stdout.

Understand the failure class

Related errors


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