anomalyco/sst · error

could not find hosted zone for domain %s

Error message

could not find hosted zone for domain %s

What it means

This resource resolves the Route53 hosted zone ID for a custom domain by listing all zones in the account and matching the domain or its parent domains (walking up labels). If no zone's name matches any suffix of the domain, lookup fails with this error, blocking Create/Update of DNS-dependent resources.

Source

Thrown at pkg/server/resource/aws-hosted-zone-lookup.go:85

		zones = append(zones, res.HostedZones...)

		if res.NextMarker == nil {
			break
		}
		nextMarker = res.NextMarker
	}

	parts := strings.Split(domain, ".")
	for i := 0; i <= len(parts)-2; i++ {
		zoneName := strings.Join(parts[i:], ".") + "."
		for _, zone := range zones {
			if *zone.Name == zoneName {
				return strings.TrimPrefix(*zone.Id, "/hostedzone/"), nil
			}
		}
	}

	return "", fmt.Errorf("could not find hosted zone for domain %s", domain)
}

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Create a Route53 hosted zone for the domain (or its parent) in the same AWS account used for deploy
  2. Fix the `domainName` in your component's `customDomain` config to exactly match the zone
  3. Verify with `aws route53 list-hosted-zones` that the zone exists under the credentials SST uses
  4. Point your AWS_PROFILE/account to the one that owns the zone, then redeploy

Example fix

// before (sst.config.ts)
customDomain: "api.exmaple.com"
// after
customDomain: "api.example.com"
Defensive patterns

Strategy: validation

Validate before calling

// verify the zone exists under the deploy credentials BEFORE deploy
import { Route53Client, ListHostedZonesCommand } from "@aws-sdk/client-route-53";
const r53 = new Route53Client({});
const zones = await r53.send(new ListHostedZonesCommand({}));
const ok = zones.HostedZones.some(z => z.Name === "example.com.");
if (!ok) throw new Error("hosted zone for domain missing in this AWS account");

Type guard

function hasZoneForDomain(zones, domain) {
  const parts = domain.split(".");
  return parts.some((_, i) =>
    zones.some(z => z.Name === parts.slice(i).join(".") + ".")
  );
}

Try / catch

try {
  await run("sst", ["deploy"]);
} catch (e) {
  const m = /could not find hosted zone for domain (.+)/.exec(String(e));
  if (m) {
    throw new Error(`Create a Route53 hosted zone for ${m[1]} in the deploy account, or fix customDomain config`, { cause: e });
  }
  throw e;
}

Prevention

When it happens

Trigger: `lookup` is called with a domain whose zone doesn't exist in the current AWS account — the domain has no hosted zone, the zone lives in a different account, the zone name has extra/missing trailing-dot normalization, or the domain is a subdomain whose zone wasn't delegated.

Common situations: Typo in `customDomain` in `sst.config.ts`; domain registered in another AWS account or at an external registrar with no Route53 zone; zone deleted after being referenced; using a subdomain like `api.example.com` when only `example.com` zone exists in a different account.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/2004b179eb1c0edf. Report an issue: GitHub.