{"record":{"id":"3e91b3bb57f59f97","repo":"anomalyco/sst","slug":"the-listen-protocol-v-listen-must-match-the-r","errorCode":null,"errorMessage":"The listen protocol \"${v.listen}\" must match the redirect protocol \"${v.redirect}\".","messagePattern":"The listen protocol \"(.+?)\" must match the redirect protocol \"(.+?)\"\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/service.ts","lineNumber":1993,"sourceCode":"                ? {\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,\n                redirectPort,\n                redirectProtocol,\n              };\n            }\n\n            const forwardParts = v.forward ? v.forward.split(\"/\") : listenParts;\n            const forwardPort = forwardParts && parseInt(forwardParts[0]);\n            const forwardProtocol = forwardParts && forwardParts[1];\n            if (protocolType(listenProtocol) !== protocolType(forwardProtocol))\n              throw new VisibleError(\n                `The listen protocol \"${v.listen}\" must match the forward protocol \"${v.forward}\".`,","sourceCodeStart":1975,"sourceCodeEnd":2011,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/service.ts#L1975-L2011","documentation":"A redirect rule's listen protocol type (application vs network) must match its redirect protocol type — you cannot listen on a network protocol and redirect to an HTTP(S) URL or vice versa. `normalizeLoadBalancer` parses `redirect` as \"port/protocol\" and throws this `VisibleError` when the protocol types differ.","triggerScenarios":"A rule such as `{ listen: \"8080/tcp\", redirect: \"443/https\" }` — protocol type of `redirect` (application) differs from `listen` (network).","commonSituations":"Setting up HTTP-to-HTTPS redirects and mistyping the listen protocol as tcp/tls; copying redirect rules between ALB and NLB services without adjusting protocols.","solutions":["Make the listen protocol the same type as the redirect protocol, e.g. `listen: \"80/http\"` with `redirect: \"443/https\"`.","For NLB (tcp/tls) rules, remove the `redirect` and handle redirection at the application layer.","Validate each rule's `listen` and `redirect` strings follow \"<port>/<protocol>\" with matching protocol families."],"exampleFix":"// before\n{ listen: \"80/tcp\", redirect: \"443/https\" }\n\n// after\n{ listen: \"80/http\", redirect: \"443/https\" }","handlingStrategy":"validation","validationCode":"const protoType = (p: string) => /^(https?)\\//.test(p) ? \"application\" : \"network\";\nfor (const r of rules) {\n  if (r.redirect) {\n    const [port, proto] = r.redirect.split(\"/\");\n    if (parseInt(port) && proto && protoType(r.listen) !== protoType(r.redirect)) {\n      throw new Error(`listen ${r.listen} and redirect ${r.redirect} protocol types differ`);\n    }\n  }\n}","typeGuard":"function redirectProtocolMatches(r: { listen: string; redirect: string }): boolean {\n  const app = (p: string) => /^https?\\//.test(p);\n  return app(r.listen) === app(r.redirect);\n}","tryCatchPattern":"try {\n  const svc = new sst.aws.Service(\"Api\", args);\n} catch (e) {\n  if (e instanceof VisibleError && e.message.includes(\"must match the redirect protocol\")) {\n    // fix listen to http/https matching the redirect\n  } else throw e;\n}","preventionTips":["Use the canonical HTTP-to-HTTPS redirect pair: listen \"80/http\", redirect \"443/https\".","Never attach `redirect` to tcp/tls/udp listeners.","Parse and validate \"<port>/<protocol>\" strings for both listen and redirect in CI."],"tags":["aws","alb","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"}