{"record":{"id":"bc3bc2b2aa45a64e","repo":"cilium/cilium","slug":"invalid-version-info","errorCode":null,"errorMessage":"invalid version info","messagePattern":"invalid version info","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/envoy/xds/server.go","lineNumber":48,"sourceCode":"\tAnyTypeURL = \"\"\n)\n\nvar (\n\t// ErrNoADSTypeURL is the error returned when receiving a request without\n\t// a type URL from an ADS stream.\n\tErrNoADSTypeURL = errors.New(\"type URL is required for ADS\")\n\n\t// ErrMismatchingTypeURL is the error returned when receiving a request with\n\t// an unexpected type URL.\n\tErrMismatchingTypeURL = errors.New(\"mismatching type URL\")\n\n\t// ErrUnknownTypeURL is the error returned when receiving a request with\n\t// an unknown type URL.\n\tErrUnknownTypeURL = errors.New(\"unknown type URL\")\n\n\t// ErrInvalidVersionInfo is the error returned when receiving a request\n\t// with a version info that is not a positive integer.\n\tErrInvalidVersionInfo = errors.New(\"invalid version info\")\n\n\t// ErrInvalidResponseNonce is returned when a request carries a response\n\t// nonce that does not match the outstanding response.\n\tErrInvalidResponseNonce = errors.New(\"invalid response nonce info\")\n\n\t// ErrInvalidNodeFormat is the error returned when receiving a request\n\t// with a node that is not a formatted correctly.\n\tErrInvalidNodeFormat = errors.New(\"invalid node format\")\n\n\t// ErrResourceWatch is the error returned whenever an internal error\n\t// occurs while waiting for new versions of resources.\n\tErrResourceWatch = errors.New(\"resource watch failed\")\n\n\t// grpcCanceled is the string prefix of any gRPC error related\n\t// to the stream being canceled. Ignore the description, as it\n\t// is derived from the client and may vary, while the code is\n\t// set by the gRPC library we link with.\n\t//","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/envoy/xds/server.go#L30-L66","documentation":"ErrInvalidVersionInfo is the sentinel error returned when a request's version info is not a positive integer. The server tracks resource versions numerically and uses the request's version_info to decide whether the client is up to date, so a version that cannot be parsed as a positive integer makes incremental processing impossible.","triggerScenarios":"processRequestStream (SotW path only, per the returner list) receives a DiscoveryRequest whose VersionInfo is non-empty but not parseable as a positive integer (e.g. letters, negative numbers, or a formatted version string).","commonSituations":"A custom client sends its own opaque version strings (e.g. git SHAs or timestamps) instead of echoing the numeric version from the last response; a client fabricates \"0\" or \"-1\" as an initial version.","solutions":["Echo back verbatim the VersionInfo from the last response received on the stream when ACKing.","Leave VersionInfo empty only for the initial request; never send arbitrary strings.","Fix custom client code that generates its own version identifiers."],"exampleFix":"// before\nreq := &discovery.DiscoveryRequest{VersionInfo: \"v1.2.3-rc1\", TypeUrl: clusterType}\n\n// after\nreq := &discovery.DiscoveryRequest{VersionInfo: lastResponse.VersionInfo, TypeUrl: clusterType} // numeric, e.g. \"42\"","handlingStrategy":"validation","validationCode":"v := req.GetVersionInfo()\nif v != \"\" {\n    if n, err := strconv.Atoi(v); err != nil || n <= 0 {\n        return status.Errorf(codes.InvalidArgument, \"version_info must be a positive integer, got %q\", v)\n    }\n}","typeGuard":"func isValidVersionInfo(v string) bool {\n    if v == \"\" { return true } // empty allowed only on the initial request\n    n, err := strconv.Atoi(v)\n    return err == nil && n > 0\n}","tryCatchPattern":"err := stream.Send(req)\nif err != nil && strings.Contains(err.Error(), \"invalid version info\") {\n    // reset req.VersionInfo to lastResponse.VersionInfo and resend\n}","preventionTips":["Echo the VersionInfo field verbatim from the last server response.","Never invent version strings (SHAs, semvers, timestamps) in custom clients.","Send VersionInfo empty only on the very first request of a stream.","Add an assertion that ACK version equals the last received response version."],"tags":["envoy","xds","grpc","validation"],"backgroundTag":"invalid-version-info","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}