{"record":{"id":"bb5c1c91c556dd9e","repo":"cilium/cilium","slug":"failed-to-read-xfrm-statistics-w","errorCode":null,"errorMessage":"failed to read xfrm statistics: %w","messagePattern":"failed to read xfrm statistics: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cilium-dbg/cmd/encrypt_status.go","lineNumber":297,"sourceCode":"\t\tListenPort: int64(wgDevice.ListenPort),\n\t\tPublicKey:  wgDevice.PublicKey.String(),\n\t\tPeerCount:  int64(len(wgDevice.Peers)),\n\t})\n\n\treturn &result, nil\n}\n\nfunc getXfrmStats(mountPoint string) (int64, map[string]int64, error) {\n\tfs, err := procfs.NewDefaultFS()\n\tif mountPoint != \"\" {\n\t\tfs, err = procfs.NewFS(mountPoint)\n\t}\n\tif err != nil {\n\t\treturn 0, nil, fmt.Errorf(\"cannot get a new proc FS: %w\", err)\n\t}\n\tstats, err := fs.NewXfrmStat()\n\tif err != nil {\n\t\treturn 0, nil, fmt.Errorf(\"failed to read xfrm statistics: %w\", err)\n\t}\n\tv := reflect.ValueOf(stats)\n\tcountErrors := int64(0)\n\terrorMap := make(map[string]int64)\n\tif v.Type().Kind() == reflect.Struct {\n\t\tfor i := range v.NumField() {\n\t\t\tname := v.Type().Field(i).Name\n\t\t\tvalue := v.Field(i).Interface().(int)\n\t\t\tif value != 0 {\n\t\t\t\tcountErrors += int64(value)\n\t\t\t\terrorMap[name] = int64(value)\n\t\t\t}\n\t\t}\n\t}\n\treturn countErrors, errorMap, nil\n}\n\nfunc extractMaxSequenceNumber(ipOutput string) (int64, error) {","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/cilium-dbg/cmd/encrypt_status.go#L279-L315","documentation":"extractMaxSequenceNumber parses the output of `ip xfrm state list reqid 1`, extracting each state's oseq field with a regex and parsing it as hex. This error is thrown when a matched oseq value cannot be parsed by strconv.ParseInt, aborting computation of the maximum IPsec sequence number.","triggerScenarios":"While running `cilium encrypt status` (dumpIPsecStatus → maxSequenceNumber → extractMaxSequenceNumber), the iproute2 output contains an `oseq 0x...` token whose captured substring is not valid base-16 (malformed, truncated, or non-hex output from a non-standard `ip` binary).","commonSituations":"Non-standard or patched iproute2 output; output truncated mid-token by the exec output capture; an `ip` shim/wrapper injecting extra text; extreme values exceeding int64 on 32-bit-like environments.","solutions":["Inspect `ip xfrm state list reqid 1` output manually for malformed oseq fields","Ensure the stock iproute2 `ip` binary is used (check PATH, remove wrappers/aliases)","Re-run after IPsec re-keying if a state was mid-update producing partial output","Patch the parser (or upgrade Cilium) if a new iproute2 format is the cause"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"out, _ := exec.Command(\"ip\", \"xfrm\", \"state\", \"list\", \"reqid\", \"1\").Output()\nif !validOseqOutput(string(out)) {\n    return fmt.Errorf(\"ip output contains unparseable oseq fields\")\n}","typeGuard":"func validOseqOutput(output string) bool {\n    re := regexp.MustCompile(`oseq[[:blank:]]0[xX]([[:xdigit:]]+)`)\n    for _, m := range re.FindAllStringSubmatch(output, -1) {\n        if _, err := strconv.ParseInt(m[1], 16, 64); err != nil { return false }\n    }\n    return true\n}","tryCatchPattern":"maxSeq, err := maxSequenceNumber()\nif err != nil && strings.Contains(err.Error(), \"failed to parse sequence number\") {\n    log.Printf(\"iproute2 output not parseable; check `ip` binary and version: %v\", err)\n}","preventionTips":["Use stock iproute2 without wrappers","Re-run after re-keying if a state was captured mid-update","Validate parseability of oseq tokens before relying on MaxSeqNumber output"],"tags":["ipsec","xfrm","parsing","strconv"],"backgroundTag":"xfrm-output-parse-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}