anomalyco/sst · error · VisibleError
You must provide the ports to expose via "loadBalancer.rules
Error message
You must provide the ports to expose via "loadBalancer.rules".
What it means
When a Service uses a managed load balancer, SST needs at least one routing rule to know which container ports to expose. `normalizeLoadBalancer` reads `loadBalancer.rules ?? loadBalancer.ports`; if both are missing or empty it throws this `VisibleError`.
Source
Thrown at platform/src/components/aws/service.ts:1954
return v;
});
}
function normalizeLoadBalancer() {
const loadBalancer = args.loadBalancer ?? args.public;
if (!loadBalancer) return;
// ALB attachment case is handled by detectAlbAttachment() before this is called
const inlineLoadBalancer = output(loadBalancer).apply(
(lb) => lb as Exclude<typeof lb, { instance: Alb }>,
);
// normalize rules
const rules = all([inlineLoadBalancer, containers]).apply(
([lb, containers]) => {
// validate rules
const lbRules = lb.rules ?? lb.ports;
if (!lbRules || lbRules.length === 0)
throw new VisibleError(
`You must provide the ports to expose via "loadBalancer.rules".`,
);
// validate container defined when multiple containers exists
if (containers.length > 1) {
lbRules.forEach((v) => {
if (!v.container)
throw new VisibleError(
`You must provide a container name in "loadBalancer.rules" when there is more than one container.`,
);
});
}
// parse protocols and ports
const rules = lbRules.map((v) => {
const listenParts = v.listen.split("/");
const listenPort = parseInt(listenParts[0]);
const listenProtocol = listenParts[1];View on GitHub (pinned to a0bd20f762)
Solutions
- Add `loadBalancer: { ports: [{ http: 80, https: 443 }] }` (or `rules: [...]`) to the Service.
- Alternatively define public ports inline on the container (`containers[].public.ports`) so routing is derived.
- If no load balancing is wanted, remove the `loadBalancer` prop entirely instead of passing an empty object.
Example fix
// before
const svc = new sst.aws.Service("Api", {
cluster,
loadBalancer: {}
});
// after
const svc = new sst.aws.Service("Api", {
cluster,
loadBalancer: { ports: [{ http: 80 }] }
}); Defensive patterns
Strategy: validation
Validate before calling
// validate before constructing the Service
const lb = args.loadBalancer;
const hasRules = lb && ((lb.rules?.length ?? 0) > 0 || (lb.ports?.length ?? 0) > 0);
if (lb && !hasRules) throw new Error("Provide loadBalancer.rules or loadBalancer.ports"); Type guard
function hasLbRules(lb?: { rules?: unknown[]; ports?: unknown[] }): boolean {
return !!lb && ((lb.rules?.length ?? 0) > 0 || (lb.ports?.length ?? 0) > 0);
} Try / catch
try {
const svc = new sst.aws.Service("Api", args);
} catch (e) {
if (e instanceof VisibleError && e.message.includes("loadBalancer.rules")) {
args.loadBalancer = { ports: [{ http: 80 }] }; // retry with defaults
} else throw e;
} Prevention
- Never pass an empty `loadBalancer: {}`; always include `ports` or `rules`.
- When migrating from inline container ports to LB rules, keep at least one rule.
- Remove the `loadBalancer` prop entirely if no public load balancing is needed.
When it happens
Trigger: Passing `loadBalancer: {}` (or an object with empty `rules`/`ports` arrays) to `new sst.aws.Service(...)` while not using inline container `public` ports.
Common situations: Migrating from an older config where ports were set on containers; refactoring `ports` into `rules` and leaving neither; template code where the ports block was deleted.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Cannot access `nodes.loadBalancer` when no public ports are
- You must provide a container name in "loadBalancer.rules" wh
- Cannot access `nodes.loadBalancer` in dev mode.
- The ALB VPC "${albVpcId}" does not match the cluster VPC "${
- Request count scaling is only supported for http/https proto
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/23da610b29efb45c.
Report an issue: GitHub.