{"record":{"id":"4e0e5f450ce5444c","repo":"istio/istio","slug":"translationerror","errorCode":"TranslationError","errorMessage":"failed to parse request timeout: %w","messagePattern":"failed to parse request timeout: %w","errorType":"validation","errorClass":"ConfigError","httpStatus":null,"severity":"error","filePath":"pilot/pkg/config/kube/agentgateway/routes.go","lineNumber":125,"sourceCode":"\t\t})\n\t}\n\treturn nil\n}\n\n// ApplyTimeouts applies timeouts to an agw route\nfunc ApplyTimeouts(rule *gatewayv1.HTTPRouteRule, route *api.Route) error {\n\tif rule == nil || rule.Timeouts == nil {\n\t\treturn nil\n\t}\n\tif route.TrafficPolicies == nil {\n\t\troute.TrafficPolicies = []*api.TrafficPolicySpec{}\n\t}\n\tvar reqDur, beDur *durationpb.Duration\n\n\tif rule.Timeouts.Request != nil {\n\t\td, err := time.ParseDuration(string(*rule.Timeouts.Request))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to parse request timeout: %w\", err)\n\t\t}\n\t\tif d != 0 {\n\t\t\t// \"Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\"\n\t\t\t// However, agentgateway already defaults to no timeout, so only set for non-zero\n\t\t\treqDur = durationpb.New(d)\n\t\t}\n\t}\n\tif rule.Timeouts.BackendRequest != nil {\n\t\td, err := time.ParseDuration(string(*rule.Timeouts.BackendRequest))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to parse backend request timeout: %w\", err)\n\t\t}\n\t\tif d != 0 {\n\t\t\t// \"Setting a timeout to the zero duration (e.g. \"0s\") SHOULD disable the timeout\"\n\t\t\t// However, agentgateway already defaults to no timeout, so only set for non-zero\n\t\t\tbeDur = durationpb.New(d)\n\t\t}\n\t}","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/istio/istio/blob/8dc789c5cf17517c64e3c36cb3288230f149dfae/pilot/pkg/config/kube/agentgateway/routes.go#L107-L143","documentation":"ApplyTimeouts parses HTTPRouteRule.spec.timeouts.request (a GEP-2257 duration string) with Go's time.ParseDuration. Strings Go cannot parse — missing unit ('30'), unknown unit ('1sec'), embedded spaces ('1 h'), or garbage — return this wrapped error, which ConvertHTTPRouteToAgw surfaces as a TranslationError condition on the route. Note Go is more permissive than GEP-2257 (it accepts '1m30s', '1.5h'), so values that parse here but violate GEP-2257 are accepted, while anything Go rejects fails.","triggerScenarios":"An HTTPRoute rule with timeouts.request set to a non-Go-duration string, e.g. \"30\", \"1sec\", \"second\", \"1 h\", \"PT30S\" (ISO-8601 by mistake), or \"500ms...\". The v1 CRD pattern normally rejects these at admission, so hitting this means the route was created programmatically or with relaxed CRDs.","commonSituations":"Pasting ISO-8601 durations from other systems; numeric-only values from templating ({{ .timeout }} without a unit suffix); generated routes from internal platforms; hand-built HTTPRoute structs in Go.","solutions":["Use a valid duration with an explicit unit: '10s', '1m', '500ms', '1.5h'","If the value comes from templating, ensure the unit is part of the template, not the variable: timeout: \"{{ .timeoutSeconds }}s\"","Apply routes with server-side dry-run so the CRD pattern catches malformed durations before istiod translates them"],"exampleFix":"# before\nspec:\n  rules:\n  - timeouts:\n      request: 30\n# after\nspec:\n  rules:\n  - timeouts:\n      request: 30s","handlingStrategy":"validation","validationCode":"if rule.Timeouts != nil && rule.Timeouts.Request != nil {\n    if _, err := time.ParseDuration(string(*rule.Timeouts.Request)); err != nil {\n        return fmt.Errorf(\"timeouts.request %q is not a valid duration (use e.g. \\\"10s\\\", \\\"1m\\\"): %w\", *rule.Timeouts.Request, err)\n    }\n}","typeGuard":"func isParseableGEPDuration(s string) bool {\n    _, err := time.ParseDuration(s)\n    return err == nil\n}","tryCatchPattern":"if err := agentgateway.ApplyTimeouts(&rule, route); err != nil {\n    if strings.Contains(err.Error(), \"request timeout\") {\n        // reject/fix the manifest: timeouts.request is not a valid duration\n    }\n    return err // propagate as TranslationError on the route status\n}","preventionTips":["Always include a unit suffix; when injecting numeric values from templates append a literal 's'","Use Go durations or GEP-2257 examples ('30s', '1m', '500ms') — never ISO-8601 ('PT30S') or bare numbers","Validate generated HTTPRoutes with kubectl apply --dry-run=server so the CRD pattern rejects bad durations early"],"tags":["istio","gateway-api","httproute","timeout","duration","translation-error","gep-2257"],"backgroundTag":null,"analyzedSha":"8dc789c5cf17517c64e3c36cb3288230f149dfae","analyzedAt":"2026-08-15T15:16:55.434Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}