anomalyco/sst · error · VisibleError
Protocols must be either all http/https, or all tcp/udp/tcp_
Error message
Protocols must be either all http/https, or all tcp/udp/tcp_udp/tls.
What it means
A Service's public ports must be uniformly either application-layer (http/https, backed by an ALB) or network-layer (tcp/udp/tcp_udp/tls, backed by an NLB) — the underlying load balancer type can't mix both. normalizePublic counts http/https ports and throws if only some of the ports are app-protocol.
Source
Thrown at platform/src/components/aws/service-v1.ts:267
const ports = pub.ports.map((v) => {
const listenParts = v.listen.split("/");
const forwardParts = v.forward ? v.forward.split("/") : listenParts;
return {
listenPort: parseInt(listenParts[0]),
listenProtocol: listenParts[1],
forwardPort: parseInt(forwardParts[0]),
forwardProtocol: forwardParts[1],
};
});
// validate protocols are consistent
const appProtocols = ports.filter(
(port) =>
["http", "https"].includes(port.listenProtocol) &&
["http", "https"].includes(port.forwardProtocol),
);
if (appProtocols.length > 0 && appProtocols.length < ports.length)
throw new VisibleError(
`Protocols must be either all http/https, or all tcp/udp/tcp_udp/tls.`,
);
// validate certificate exists for https/tls protocol
ports.forEach((port) => {
if (["https", "tls"].includes(port.listenProtocol) && !pub.domain) {
throw new VisibleError(
`You must provide a custom domain for ${port.listenProtocol.toUpperCase()} protocol.`,
);
}
});
return ports;
});
const domain = output(args.public).apply((pub) => {
if (!pub.domain) return undefined;
View on GitHub (pinned to a0bd20f762)
Solutions
- Make all `public.ports` entries use http/https protocols
- Or make all entries use tcp/udp/tcp_udp/tls protocols
- Split into two separate Service components if both protocol families are genuinely needed
Example fix
// before
public: { ports: [{ listen: "80/http" }, { listen: "22/tcp" }] }
// after
public: { ports: [{ listen: "80/http" }, { listen: "443/https" }] } Defensive patterns
Strategy: validation
Validate before calling
const app = ["http","https"]; const net = ["tcp","udp","tcp_udp","tls"];
const protos = args.public?.ports?.map(p => p.listen.split("/")[1]) ?? [];
const allApp = protos.every(p => app.includes(p));
const allNet = protos.every(p => net.includes(p));
if (protos.length && !allApp && !allNet) throw new Error("mixing app and network protocols in public.ports"); Prevention
- Pick one protocol family per service
- Use ALB-style http/https for web APIs, NLB-style tcp/udp for raw sockets
- Split mixed workloads into separate services
When it happens
Trigger: Mixing e.g. `[{ listen: "80/http" }, { listen: "22/tcp" }]` in `public.ports`; adding one TCP port to an otherwise HTTP service.
Common situations: Exposing both an HTTP API and a raw TCP port (e.g. SSH, game server) on one service; incremental edits adding a port with a different protocol.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- You must provide the ports to expose via "public.ports".
- The listen protocol "${v.listen}" must match the forward pro
- Protocols must be either all http/https, or all tcp/udp/tcp_
- Cannot configure health check for "${k}". Make sure it is de
- You must provide at least one rule in "loadBalancer.rules" w
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/6a994da6e06fdc4f.
Report an issue: GitHub.