{"record":{"id":"d580fa7ad9c59bbe","repo":"cilium/cilium","slug":"failed-to-unmarshal-bgp-routes-from-s-w","errorCode":null,"errorMessage":"failed to unmarshal bgp routes from %s: %w","messagePattern":"failed to unmarshal bgp routes from (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cilium-cli/bgp/routes.go","lineNumber":146,"sourceCode":"}\n\nfunc (s *Status) fetchRoutesFromPod(ctx context.Context, fetchCmd []string, pod *corev1.Pod) ([]*models.BgpRoute, error) {\n\toutput, errOutput, err := s.client.ExecInPodWithStderr(ctx, pod.Namespace, pod.Name, defaults.AgentContainerName, fetchCmd)\n\tif err != nil {\n\t\tvar errStr string\n\t\tif errOutput.String() != \"\" {\n\t\t\terrStr = strings.TrimSpace(errOutput.String())\n\t\t} else {\n\t\t\terrStr = err.Error()\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to fetch bgp state from %s: (%s)\", pod.Name, errStr)\n\t}\n\n\tbgpRoutes := make([]*models.BgpRoute, 0)\n\n\terr = json.Unmarshal(output.Bytes(), &bgpRoutes)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal bgp routes from %s: %w\", pod.Name, err)\n\t}\n\n\treturn bgpRoutes, nil\n}\n\nfunc (s *Status) writeRoutes(res map[string][]*models.BgpRoute, printPeer bool) error {\n\tif s.params.Output == status.OutputJSON {\n\t\tjsonStatus, err := json.MarshalIndent(res, \"\", \" \")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfmt.Println(string(jsonStatus))\n\t} else {\n\t\tprintRouteSummary(os.Stdout, res, printPeer)\n\t}\n\n\treturn nil\n}","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/cilium-cli/bgp/routes.go#L128-L164","documentation":"After a successful exec of `cilium bgp routes ... -o json` in the agent pod, fetchRoutesFromPod (cilium-cli/bgp/routes.go:130) unmarshals stdout into []*models.BgpRoute. A mismatch between the agent's JSON output and this schema produces \"failed to unmarshal bgp routes from <pod>: %w\". It means the routes payload is not valid JSON of the expected BgpRoute array shape.","triggerScenarios":"Running `cilium bgp routes ...` where the in-pod command exits 0 but its JSON cannot be decoded into []*models.BgpRoute (wrong field types, unexpected shape, extra non-JSON output on stdout).","commonSituations":"Cilium CLI and agent version skew (agent emits an older/newer route schema); BGP routes output containing warnings interleaved with JSON; the agent returning an empty or partial response due to a crashed BGP control plane while still exiting 0.","solutions":["Align cilium-cli and Cilium agent versions so the `bgp routes -o json` schema matches models.BgpRoute.","Inspect raw output via `kubectl exec <cilium-pod> -c cilium-agent -- cilium bgp routes ... -o json` and look for non-JSON text or unexpected field types.","Confirm BGP is fully initialized on the node (peers established) so the agent returns a well-formed routes list.","Retry after restarting the agent pod if it emitted a truncated/partial response."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// pre-check the raw payload decodes as expected before relying on the CLI result:\nRAW=$(kubectl exec <cilium-pod> -n kube-system -c cilium-agent -- cilium bgp routes available ipv4 unicast -o json)\necho \"$RAW\" | jq -e 'type == \"array\"' >/dev/null && echo OK || echo \"unexpected payload shape\"","typeGuard":"// Go: distinguish schema mismatch from malformed JSON\nfunc isUnmarshalTypeError(err error) bool {\n    var typeErr *json.UnmarshalTypeError\n    return errors.As(err, &typeErr)\n}\n// if isUnmarshalTypeError(err): agent JSON shape differs from models.BgpRoute -> version skew","tryCatchPattern":"// Go\n_, err := fetchRoutesFromPod(ctx, fetchCmd, pod)\nif err != nil {\n    var typeErr *json.UnmarshalTypeError\n    if errors.As(err, &typeErr) {\n        return fmt.Errorf(\"route schema mismatch (field %s): upgrade cilium-cli/agent to matching versions\", typeErr.Field)\n    }\n    return err\n}","preventionTips":["Keep cilium-cli and Cilium agent on matching versions to avoid BgpRoute schema drift.","Check `jq 'type == \"array\"'` on the agent's raw `-o json` output when debugging.","Restart unhealthy agents; truncated stdout can yield unparseable payloads.","Avoid wrappers that interleave log output into the exec stdout stream."],"tags":["kubernetes","cilium","bgp","json-unmarshal","cli"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}