{"record":{"id":"7b9b2e8b7db75692","repo":"anomalyco/sst","slug":"invalid-rule-conditions-for-listen-protocol-v-l","errorCode":null,"errorMessage":"Invalid rule conditions for listen protocol \"${v.listen}\". Only \"http\" protocols support conditions.","messagePattern":"Invalid rule conditions for listen protocol \"(.+?)\"\\. Only \"http\" protocols support conditions\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/service.ts","lineNumber":1982,"sourceCode":"                );\n            });\n          }\n\n          // parse protocols and ports\n          const rules = lbRules.map((v) => {\n            const listenParts = v.listen.split(\"/\");\n            const listenPort = parseInt(listenParts[0]);\n            const listenProtocol = listenParts[1];\n            const listenConditions =\n              v.conditions || v.path\n                ? {\n                    path: v.conditions?.path ?? v.path,\n                    query: v.conditions?.query,\n                    header: v.conditions?.header,\n                  }\n                : undefined;\n            if (protocolType(listenProtocol) === \"network\" && listenConditions)\n              throw new VisibleError(\n                `Invalid rule conditions for listen protocol \"${v.listen}\". Only \"http\" protocols support conditions.`,\n              );\n\n            const redirectParts = v.redirect?.split(\"/\");\n            const redirectPort = redirectParts && parseInt(redirectParts[0]);\n            const redirectProtocol = redirectParts && redirectParts[1];\n            if (redirectPort && redirectProtocol) {\n              if (\n                protocolType(listenProtocol) !== protocolType(redirectProtocol)\n              )\n                throw new VisibleError(\n                  `The listen protocol \"${v.listen}\" must match the redirect protocol \"${v.redirect}\".`,\n                );\n              return {\n                type: \"redirect\" as const,\n                listenPort,\n                listenProtocol,\n                listenConditions,","sourceCodeStart":1964,"sourceCodeEnd":2000,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/service.ts#L1964-L2000","documentation":"ALB path/query/header-based routing conditions only exist on application (HTTP/HTTPS) listeners. When a rule listens on a network protocol (tcp/tls/udp) but also specifies `conditions` (path, query, or header), SST's `normalizeLoadBalancer` throws this `VisibleError` because NLB listeners cannot evaluate such conditions.","triggerScenarios":"A load balancer rule like `{ listen: \"9000/tcp\", conditions: { path: \"/api\" } }` — network listen protocol combined with any `conditions` object (including legacy `path`).","commonSituations":"Copying an HTTP rule's conditions onto a TCP/UDP rule when adding a non-HTTP port; switching `listen` from \"443/https\" to \"443/tls\" and leaving `path`/`conditions` in place.","solutions":["Remove the `conditions` (and `path`) fields from rules that listen on tcp/tls/udp protocols.","Change the listen protocol to \"http\"/\"https\" if host/path-based routing is actually required.","Move path-based routing to an application-level router (e.g. API Gateway or an app-level reverse proxy) for network listeners."],"exampleFix":"// before\n{ listen: \"9000/tcp\", conditions: { path: \"/api\" }, forward: \"9000/tcp\" }\n\n// after\n{ listen: \"9000/tcp\", forward: \"9000/tcp\" }","handlingStrategy":"validation","validationCode":"const isNetworkProto = (p: string) => /^(tcp|tls|udp|tcp_udp)\\//.test(p);\nfor (const r of rules) {\n  if (isNetworkProto(r.listen) && (r.conditions || r.path)) {\n    throw new Error(`Rule ${r.listen} cannot use conditions with a network protocol`);\n  }\n}","typeGuard":"function ruleConditionsValid(r: { listen: string; conditions?: object; path?: string }): boolean {\n  const network = /^(tcp|tls|udp)/.test(r.listen);\n  return !(network && (r.conditions !== undefined || r.path !== undefined));\n}","tryCatchPattern":"try {\n  const svc = new sst.aws.Service(\"Api\", args);\n} catch (e) {\n  if (e instanceof VisibleError && e.message.includes(\"Only \\\"http\\\" protocols support conditions\")) {\n    args.loadBalancer.rules = args.loadBalancer.rules.map(({ conditions, path, ...r }) => r);\n  } else throw e;\n}","preventionTips":["Strip `conditions`/`path` from any rule listening on tcp/tls/udp.","Only use path/query/header routing on http/https listeners.","Lint load-balancer rule arrays for protocol/condition compatibility."],"tags":["aws","alb","nlb","configuration","routing","sst"],"backgroundTag":"invalid-load-balancer-rule","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}