{"record":{"id":"dbd7ffdbff3d4762","repo":"cilium/cilium","slug":"unable-to-parse-cilium-version-on-pod-q-w-dbd7ff","errorCode":null,"errorMessage":"unable to parse cilium version on pod %q: %w","messagePattern":"unable to parse cilium version on pod %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cilium-cli/k8s/client.go","lineNumber":1096,"sourceCode":"\n// GetCiliumVersion returns a semver.Version representing the version of cilium\n// running in the cilium-agent pod\nfunc (c *Client) GetCiliumVersion(ctx context.Context, p *corev1.Pod) (*semver.Version, error) {\n\to, _, err := c.ExecInPodWithStderr(\n\t\tctx,\n\t\tp.Namespace,\n\t\tp.Name,\n\t\tdefaults.AgentContainerName,\n\t\t[]string{\"cilium\", \"version\", \"-o\", \"jsonpath={$.Daemon.Version}\"},\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to fetch cilium version on pod %q: %w\", p.Name, err)\n\t}\n\n\tv, _, _ := strings.Cut(strings.TrimSpace(o.String()), \"-\") // strips proprietary -releaseX suffix\n\tpodVersion, err := semver.Parse(v)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to parse cilium version on pod %q: %w\", p.Name, err)\n\t}\n\n\treturn &podVersion, nil\n}\n\nfunc (c *Client) GetRunningCiliumVersion(ciliumHelmReleaseName string) (string, error) {\n\tm, err := action.NewGetMetadata(c.HelmActionConfig).Run(ciliumHelmReleaseName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn m.Version, nil\n}\n\nfunc (c *Client) ListCiliumLocalRedirectPolicies(ctx context.Context, namespace string, opts metav1.ListOptions) (*ciliumv2.CiliumLocalRedirectPolicyList, error) {\n\treturn c.CiliumClientset.CiliumV2().CiliumLocalRedirectPolicies(namespace).List(ctx, opts)\n}\n\nfunc (c *Client) GetServerVersion() (*semver.Version, error) {","sourceCodeStart":1078,"sourceCodeEnd":1114,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/cilium-cli/k8s/client.go#L1078-L1114","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nv, _, _ := strings.Cut(strings.TrimSpace(o.String()), \"-\")\npodVersion, err := semver.Parse(v)\n// after\nraw := strings.TrimSpace(o.String())\nif raw == \"\" {\n    return nil, fmt.Errorf(\"empty cilium version output from pod %q\", p.Name)\n}\nv, _, _ := strings.Cut(raw, \"-\")\nif !semver.IsValid(v) { // guard against non-semver custom builds\n    return nil, fmt.Errorf(\"cilium pod %q reports non-semver version %q\", p.Name, v)\n}\npodVersion, err := semver.Parse(v)","handlingStrategy":"validation","validationCode":"out, _, err := client.ExecInPodWithStderr(ctx, ns, podName, \"cilium-agent\",\n    []string{\"cilium\", \"version\", \"-o\", \"jsonpath={$.Daemon.Version}\"})\nif err != nil { return err }\nv := strings.TrimSpace(out.String())\nif _, perr := semver.Parse(strings.Cut(v, \"-\")[0]); perr != nil {\n    return fmt.Errorf(\"pod reports non-semver cilium version %q\", v)\n}","typeGuard":"func isSemver(s string) bool {\n    _, err := semver.Parse(strings.TrimSpace(strings.Cut(s, \"-\")[0]))\n    return err == nil\n}","tryCatchPattern":"ver, err := client.GetCiliumVersion(ctx, pod)\nif err != nil && strings.Contains(err.Error(), \"unable to parse cilium version\") {\n    // agent output not semver: fall back to Helm release version or skip version gate\n    return client.GetRunningCiliumVersion(releaseName)\n}","preventionTips":["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"],"tags":["cilium","semver","parsing"],"backgroundTag":"version-parse-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}