grpc/grpc-go · error
rls: failed to parse max_age in route lookup config %+v: %v
Error message
rls: failed to parse max_age in route lookup config %+v: %v
What it means
Returned by parseRLSProto (config.go:227-230) when convertDuration fails on RouteLookupConfig.max_age for the same reason as the timeout: the google.protobuf.Duration is out of range (durationpb.CheckValid rejects invalid seconds/nanos). Note valid values are capped to 5 minutes (maxMaxAge) after parsing.
Source
Thrown at balancer/rls/config.go:229
}
lookupServiceTimeout, err := convertDuration(rlsProto.GetLookupServiceTimeout())
if err != nil {
return nil, fmt.Errorf("rls: failed to parse lookup_service_timeout in route lookup config %+v: %v", rlsProto, err)
}
if lookupServiceTimeout == 0 {
lookupServiceTimeout = defaultLookupServiceTimeout
}
// Validations performed here:
// - if `max_age` > 5m, it should be set to 5 minutes
// only if stale age is not set
// - if `stale_age` > `max_age`, ignore it
// - if `stale_age` is set, then `max_age` must also be set
maxAgeSet := false
maxAge, err := convertDuration(rlsProto.GetMaxAge())
if err != nil {
return nil, fmt.Errorf("rls: failed to parse max_age in route lookup config %+v: %v", rlsProto, err)
}
if maxAge == 0 {
maxAge = maxMaxAge
} else {
maxAgeSet = true
}
staleAgeSet := false
staleAge, err := convertDuration(rlsProto.GetStaleAge())
if err != nil {
return nil, fmt.Errorf("rls: failed to parse staleAge in route lookup config %+v: %v", rlsProto, err)
}
if staleAge == 0 {
staleAge = maxMaxAge
} else {
staleAgeSet = true
}
View on GitHub (pinned to 03255a9237)
Solutions
- Provide a sane max_age (0 to use the 5-minute default, or <= 5m); the policy caps it at 5 minutes anyway.
- Build the Duration with durationpb.New(time.Duration) to guarantee validity.
- Check the control plane's max_age generation.
Example fix
// before
rlc.MaxAge = &durationpb.Duration{ Seconds: -1, Nanos: -1000000000 } // invalid nanos
// after
rlc.MaxAge = durationpb.New(5 * time.Minute) Defensive patterns
Strategy: validation
Validate before calling
func validateMaxAge(d *durationpb.Duration) error {
if d == nil { return nil }
return d.CheckValid()
} Prevention
- Use durationpb.New to build max_age (capped at 5m anyway).
- 0 means use the 5m default; only structurally invalid values fail.
When it happens
Trigger: max_age Duration proto is structurally invalid (out-of-range seconds or nanos). A value of 0 is valid (defaults to 5m); only structurally invalid Durations trigger this.
Common situations: Control-plane overflow building the Duration. Manually setting Nanos out of [-1e9,1e9).
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- rls: failed to parse lookup_service_timeout in route lookup
- rls: failed to parse staleAge in route lookup config %+v: %v
- rls: bad RouteLookupConfig proto %+v: %v
- rls: json unmarshal failed for service config %+v: %v
- rls: bad control channel service config %q: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/a6bd2e4f62b0ff2a.
Report an issue: GitHub.