{"record":{"id":"c2ce7e005cb541c0","repo":"istio/istio","slug":"http-route-rule-cannot-contain-both-direct-respons","errorCode":null,"errorMessage":"HTTP route rule cannot contain both direct_response and redirect","messagePattern":"HTTP route rule cannot contain both direct_response and redirect","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/validation/virtualservice.go","lineNumber":224,"sourceCode":"\t\t}\n\t}\n\n\t// check for conflicts\n\tif http.Redirect != nil {\n\t\tif len(http.Route) > 0 {\n\t\t\terrs = appendErrors(errs, errors.New(\"HTTP route cannot contain both route and redirect\"))\n\t\t}\n\n\t\tif http.Fault != nil {\n\t\t\terrs = appendErrors(errs, errors.New(\"HTTP route cannot contain both fault and redirect\"))\n\t\t}\n\n\t\tif http.Rewrite != nil {\n\t\t\terrs = appendErrors(errs, errors.New(\"HTTP route rule cannot contain both rewrite and redirect\"))\n\t\t}\n\n\t\tif http.DirectResponse != nil {\n\t\t\terrs = appendErrors(errs, errors.New(\"HTTP route rule cannot contain both direct_response and redirect\"))\n\t\t}\n\t} else if http.DirectResponse != nil {\n\t\tif len(http.Route) > 0 {\n\t\t\terrs = appendErrors(errs, errors.New(\"HTTP route cannot contain both route and direct_response\"))\n\t\t}\n\n\t\tif http.Fault != nil {\n\t\t\terrs = appendErrors(errs, errors.New(\"HTTP route cannot contain both fault and direct_response\"))\n\t\t}\n\n\t\tif http.Rewrite != nil {\n\t\t\terrs = appendErrors(errs, errors.New(\"HTTP route rule cannot contain both rewrite and direct_response\"))\n\t\t}\n\n\t\tif http.Redirect != nil {\n\t\t\terrs = appendErrors(errs, errors.New(\"HTTP route rule cannot contain both redirect and direct_response\"))\n\t\t}\n\t} else if len(http.Route) == 0 {","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/istio/istio/blob/8dc789c5cf17517c64e3c36cb3288230f149dfae/pkg/config/validation/virtualservice.go#L206-L242","documentation":"Both 'direct_response' and 'redirect' are terminal actions — one returns a fixed response locally, the other instructs the client to go elsewhere. Setting both on a single http route is ambiguous and rejected by validation.","triggerScenarios":"An http route containing both 'directResponse:' (status/body) and 'redirect:'.","commonSituations":"A/B testing config or migration from returning a static error page to redirecting, with the old block left behind.","solutions":["Keep 'directResponse' if a local fixed response is wanted; remove 'redirect'","Keep 'redirect' if the client should be sent elsewhere; remove 'directResponse'","Use match conditions to split the behaviors across two routes if both are needed"],"exampleFix":"# before\nhttp:\n- match: [{uri: {prefix: /gone}}]\n  directResponse: {status: 410}\n  redirect: {uri: /}\n\n# after\nhttp:\n- match: [{uri: {prefix: /gone}}]\n  directResponse: {status: 410}","handlingStrategy":"validation","validationCode":"func directResponseAndRedirectCompatible(http *networking.HTTPRoute) bool {\n\treturn !(http.GetDirectResponse() != nil && http.GetRedirect() != nil)\n}","typeGuard":"func hasDirectResponseRedirectConflict(http *networking.HTTPRoute) bool {\n\treturn http.GetDirectResponse() != nil && http.GetRedirect() != nil\n}","tryCatchPattern":null,"preventionTips":["directResponse and redirect are both terminal — choose exactly one","Use distinct match conditions when some paths must answer locally and others redirect"],"tags":["istio","virtualservice","direct-response","redirect","conflict"],"backgroundTag":null,"analyzedSha":"8dc789c5cf17517c64e3c36cb3288230f149dfae","analyzedAt":"2026-08-15T15:16:55.434Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}