{"record":{"id":"44670102dbd81ccd","repo":"grpc/grpc-go","slug":"rls-failed-to-parse-lookup-service-timeout-in-rou","errorCode":null,"errorMessage":"rls: failed to parse lookup_service_timeout in route lookup config %+v: %v","messagePattern":"rls: failed to parse lookup_service_timeout in route lookup config %\\+v: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/rls/config.go","lineNumber":215,"sourceCode":"\t}\n\tparsedTarget, err := url.Parse(lookupService)\n\tif err != nil {\n\t\t// url.Parse() fails if scheme is missing. Retry with default scheme.\n\t\tparsedTarget, err = url.Parse(resolver.GetDefaultScheme() + \":///\" + lookupService)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"rls: invalid target URI in lookup_service %s\", lookupService)\n\t\t}\n\t}\n\tif parsedTarget.Scheme == \"\" {\n\t\tparsedTarget.Scheme = resolver.GetDefaultScheme()\n\t}\n\tif resolver.Get(parsedTarget.Scheme) == nil {\n\t\treturn nil, fmt.Errorf(\"rls: unregistered scheme in lookup_service %s\", lookupService)\n\t}\n\n\tlookupServiceTimeout, err := convertDuration(rlsProto.GetLookupServiceTimeout())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rls: failed to parse lookup_service_timeout in route lookup config %+v: %v\", rlsProto, err)\n\t}\n\tif lookupServiceTimeout == 0 {\n\t\tlookupServiceTimeout = defaultLookupServiceTimeout\n\t}\n\n\t// Validations performed here:\n\t// - if `max_age` > 5m, it should be set to 5 minutes\n\t//   only if stale age is not set\n\t// - if `stale_age` > `max_age`, ignore it\n\t// - if `stale_age` is set, then `max_age` must also be set\n\tmaxAgeSet := false\n\tmaxAge, err := convertDuration(rlsProto.GetMaxAge())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rls: failed to parse max_age in route lookup config %+v: %v\", rlsProto, err)\n\t}\n\tif maxAge == 0 {\n\t\tmaxAge = maxMaxAge\n\t} else {","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/balancer/rls/config.go#L197-L233","documentation":"Emitted from parseRLSProto (config.go:215) when convertDuration fails for RouteLookupConfig.lookup_service_timeout. convertDuration calls durationpb.Duration.CheckValid, which rejects out-of-range seconds/nanos (approx |seconds| < ~3e11 and nanos in [0, 1e9)). This is the RLS RPC deadline; a zero value is allowed and defaults to 10s.","triggerScenarios":"lookup_service_timeout is a google.protobuf.Duration whose seconds field exceeds the valid range or whose nanos field is >= 1e9 or negative-and-out-of-range.","commonSituations":"A control-plane bug emitting INT64 seconds (e.g. milliseconds passed as seconds); a hand-written proto duration with nanos=2000000000; schema-mismatch where a plain JSON number is fed where a duration object is expected (that typically fails earlier at protojson).","solutions":["Set lookup_service_timeout to a well-formed duration such as {\"seconds\": 10} or omit it to take the 10s default.","Audit the control-plane code that serializes the duration to confirm it uses durationpb.New with a time.Duration.","Cap any user-supplied value to a sane range before serialization."],"exampleFix":"// before\n\"lookupServiceTimeout\": { \"seconds\": 9999999999999999999, \"nanos\": 0 }\n\n// after\n\"lookupServiceTimeout\": { \"seconds\": 10 }","handlingStrategy":"validation","validationCode":"func validateLookupTimeout(d *durationpb.Duration) error {\n    if d == nil {\n        return nil // zero is valid; defaults to 10s\n    }\n    if _, err := d.AsDuration(), d.CheckValid(); err != nil {\n        return fmt.Errorf(\"lookup_service_timeout is invalid: %w\", err)\n    }\n    return nil\n}","typeGuard":"func isValidLookupTimeout(d *durationpb.Duration) bool {\n    if d == nil {\n        return true\n    }\n    return d.CheckValid() == nil\n}","tryCatchPattern":null,"preventionTips":["Produce durations with durationpb.New(time.Duration), never by hand-setting fields.","Treat omitted lookup_service_timeout as acceptable (10s default applies).","Range-check user-supplied durations before serialization on the control plane."],"tags":["rls","duration","validation","proto"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}