{"record":{"id":"da52f1f65a861aeb","repo":"cilium/cilium","slug":"listener-is-not-allowed-on-ingress-s","errorCode":null,"errorMessage":"Listener is not allowed on ingress (%s)","messagePattern":"Listener is not allowed on ingress \\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/policy/api/rule_validation.go","lineNumber":670,"sourceCode":"\t\tif isZero {\n\t\t\thaveZeroPort = true\n\t\t}\n\t\t// DNS L7 rules can be TCP, UDP or ANY, all others are TCP only.\n\t\tswitch {\n\t\tcase pr.Rules.IsEmpty(), hasDNSRules:\n\t\t\t// nothing to do if no rules OR they are DNS rules (note the comma above)\n\t\tcase pr.Ports[i].Protocol != ProtoTCP:\n\t\t\treturn fmt.Errorf(\"L7 rules can only apply to TCP (not %s) except for DNS rules\", pr.Ports[i].Protocol)\n\t\t}\n\t}\n\n\tlistener := pr.Listener\n\tif listener != nil {\n\t\t// For now we have only tested custom listener support on the egress path.  TODO\n\t\t// (jrajahalme): Lift this limitation in follow-up work once proper testing has been\n\t\t// done on the ingress path.\n\t\tif ingress && !TestAllowIngressListener {\n\t\t\treturn fmt.Errorf(\"Listener is not allowed on ingress (%s)\", listener.Name)\n\t\t}\n\t\t// There is no guarantee that Listener will support Cilium policy enforcement.\n\t\tif !pr.Rules.IsEmpty() {\n\t\t\treturn fmt.Errorf(\"Listener is not allowed with L7 rules (%s)\", listener.Name)\n\t\t}\n\t}\n\n\t// Sanitize L7 rules\n\tif !pr.Rules.IsEmpty() {\n\t\tif haveZeroPort {\n\t\t\treturn errors.New(\"L7 rules can not be used when a port is 0\")\n\t\t}\n\n\t\tif err := pr.Rules.Validate(pr.Ports); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil","sourceCodeStart":652,"sourceCodeEnd":688,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/policy/api/rule_validation.go#L652-L688","documentation":"Cilium's policy rule validation rejects a custom Envoy `Listener` on ingress network policy rules. Custom listeners are only supported on the egress path because that is the only path that has been adequately tested; a compile-time-style test flag (TestAllowIngressListener) can override this for testing. The check exists so users do not rely on an untested/unsupported configuration that may silently not enforce policy as expected.","triggerScenarios":"Calling PortRule.Validate (via a CiliumNetworkPolicy rule Validate) with a rule whose `listener` field is set while the rule is an ingress rule and TestAllowIngressListener is false.","commonSituations":"Users copying an egress rule with a `listener:` block into an ingress section of a CiliumNetworkPolicy; tooling generating symmetric ingress/egress rules; upgrading Cilium after using listeners on egress and mirroring them to ingress.","solutions":["Remove the `listener` field from the ingress rule, keeping it only on egress rules","Move the traffic control the listener provided into an egress rule instead","If this is for CI/testing only, set TestAllowIngressListener=true in the test harness (not production)","If ingress listener support is needed, follow/contrast upstream Cilium issues tracking lifting this limitation"],"exampleFix":"// before (ingress rule)\napiVersion: cilium.io/v2\nkind: CiliumNetworkPolicy\nspec:\n  ingress:\n  - toPorts:\n    - ports: [{port: '8080'}]\n      listener: my-envoy-listener\n// after\n  ingress:\n  - toPorts:\n    - ports: [{port: '8080'}]","handlingStrategy":"validation","validationCode":"func hasIngressListener(rule api.Rule) bool {\n\tif rule.EndpointSelector != nil && !rule.Ingress(nil, nil) {\n\t\t// caller should determine direction; simplest guard: scan ingress port rules\n\t}\n\tfor _, r := range rule.IngressRules {\n\t\tfor _, p := range r.ToPorts {\n\t\t\tif p.Listener != nil {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n// reject or strip listener before calling Validate","typeGuard":null,"tryCatchPattern":"err := rule.Validate(state, logger)\nif err != nil && strings.Contains(err.Error(), \"Listener is not allowed on ingress\") {\n\t// strip listener from ingress toPorts or move rule to egress and re-validate\n}","preventionTips":["Never set `listener` under ingress toPorts in production policies","Keep listener-based rules in egress sections only","Add CI linting that flags listener fields in ingress rules"],"tags":["cilium","network-policy","ingress","envoy-listener"],"backgroundTag":"unsupported-policy-field","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}