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
- Run `kubectl exec <pod> -c cilium-agent -- cilium version -o jsonpath={$.Daemon.Version}` to see the raw output and fix the build/tag
- Ensure the image is an official cilium release with a valid semver tag
- Check for wrapper scripts or sidecar logs polluting stdout before the jsonpath output
- 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
- Only run version checks against official cilium images with valid semver tags
- Inspect raw `cilium version` output manually when using custom/patched builds
- Avoid wrappers that print extra text to the exec's stdout
- Strip expected suffixes (-releaseX) before parsing, as the library does
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to parse %s: %w
- Error parsing Cilium network policies: %w
- Error parsing Cilium Cluster Wide network policies: %w
- invalid exit code %q in error %s
- failed to parse kernel version: %w
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/dbd7ffdbff3d4762.
Report an issue: GitHub.