anomalyco/sst · error · VisibleError
Set "vpc.publicSubnets" on the Cluster to use "public" on th
Error message
Set "vpc.publicSubnets" on the Cluster to use "public" on the "${name}" Task. What it means
When a Task is attached to an existing Cluster and marked `public: true`, the task's ENIs must land in public subnets so they get internet-facing IPs. normalizeVpc inspects the cluster's `vpc.publicSubnets` list and throws if it is empty or undefined, because a public task cannot be scheduled correctly in a VPC without public subnets.
Source
Thrown at platform/src/components/aws/task.ts:417
// "vpc" is a Vpc component
if (args.cluster.vpc instanceof Vpc) {
const vpc = args.cluster.vpc;
return {
id: vpc.id,
isSstVpc: true,
publicSubnets: vpc.publicSubnets,
containerSubnets: vpc.publicSubnets,
securityGroups: vpc.securityGroups,
};
}
// "vpc" is object
return {
id: output(args.cluster.vpc).apply((v) => v.id),
isSstVpc: false,
publicSubnets: output(args.cluster.vpc).apply((v) => {
if (isPublic && !v.publicSubnets?.length)
throw new VisibleError(
`Set "vpc.publicSubnets" on the Cluster to use "public" on the "${name}" Task.`,
);
return (v.publicSubnets ?? []).map((v) => output(v));
}),
containerSubnets: output(args.cluster.vpc).apply((v) =>
v.containerSubnets.map((v) => output(v)),
),
securityGroups: output(args.cluster.vpc).apply((v) =>
v.securityGroups.map((v) => output(v)),
),
};
}
function createPublicSecurityGroup() {
if (!isPublic) return;
return new ec2.SecurityGroup(
`${name}PublicSecurityGroup`,View on GitHub (pinned to a0bd20f762)
Solutions
- Set `publicSubnets` on the Cluster's `vpc` argument to an array of public subnet IDs.
- If the VPC is an SST `sst.aws.Vpc` reference, recreate/update it with `publicSubnets` configured and redeploy, then redeploy the app.
- If the task does not actually need to be public, set `public: false` so it can use private/container subnets.
Example fix
// before
new sst.aws.Cluster("Cluster", {
vpc: { id: "vpc-123", containerSubnets: ["subnet-a"], privateSubnets: ["subnet-b"] }
});
new sst.aws.Task("Task", { cluster: cluster, public: true });
// after
new sst.aws.Cluster("Cluster", {
vpc: {
id: "vpc-123",
containerSubnets: ["subnet-a"],
privateSubnets: ["subnet-b"],
publicSubnets: ["subnet-c"]
}
});
new sst.aws.Task("Task", { cluster: cluster, public: true }); Defensive patterns
Strategy: validation
Validate before calling
const clusterVpc = { id: "vpc-123", publicSubnets: [], containerSubnets: ["subnet-a"] };
if (isPublicTask && (!clusterVpc.publicSubnets || clusterVpc.publicSubnets.length === 0)) {
throw new Error("Cluster vpc must define publicSubnets for tasks with public: true");
} Type guard
function hasPublicSubnets(v: { publicSubnets?: string[] }): v is { publicSubnets: string[] } {
return Array.isArray(v.publicSubnets) && v.publicSubnets.length > 0;
} Prevention
- When enabling `public: true` on a Task, immediately add `publicSubnets` to the Cluster's vpc config.
- Prefer referencing an `sst.aws.Vpc` component (which manages subnets) over hand-written vpc object literals.
- Document required subnet roles (public/private/container) in your infra config module.
When it happens
Trigger: Creating `new sst.aws.Task("X", { cluster: <a cluster whose vpc has no publicSubnets>, public: true })`, or pointing the task at a Cluster built from a `vpc` object literal that omits `publicSubnets`.
Common situations: Using a VPC created with only private subnets (default NAT-less setup), referencing an external/pre-existing VPC whose `publicSubnets` array was not provided to the Cluster, or forgetting to add public subnets after enabling `public: true` on a previously private task.
Related errors
- The VPC configured for the service does not have NAT enabled
- You cannot provide both "vpc.containerSubnets" and "vpc.serv
- Missing "vpc.containerSubnets" for the "${name}" Cluster com
- The ALB VPC "${albVpcId}" does not match the cluster VPC "${
- Failed to describe task
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/184242870e634b08.
Report an issue: GitHub.