serverless/serverless · error · ServerlessError
API_GATEWAY_CUSTOM_DOMAIN_FETCH_FAILED
API_GATEWAY_CUSTOM_DOMAIN_FETCH_FAILED
Error message
V1 - Unable to fetch information about '${domain.givenDomainName}':\n${err.message} What it means
Thrown by APIGatewayV1Wrapper.getCustomDomain when GetDomainNameCommand fails for any reason OTHER than a silent 404. The branch at line 108 suppresses only a 404 when silent=true; every other status (or a non-silent 404) bubbles up as this error. It is the read-path counterpart to creation failures and is used during deploy/teardown to decide whether a domain already exists.
Source
Thrown at packages/serverless/lib/plugins/aws/domains/aws/api-gateway-v1-wrapper.js:109
/**
* Get Custom Domain Info
* @param {DomainConfig} domain
* @param {boolean} silent To issue an error or not. Not by default.
* @returns {Promise<DomainInfo>}
*/
async getCustomDomain(domain, silent = true) {
// Make API call
try {
const domainInfo = await this.apiGateway.send(
new GetDomainNameCommand({
domainName: domain.givenDomainName,
}),
)
return new DomainInfo(domainInfo)
} catch (err) {
const statusCode = err.$metadata?.httpStatusCode
if (!statusCode || statusCode !== 404 || !silent) {
throw new ServerlessError(
`V1 - Unable to fetch information about '${domain.givenDomainName}':\n${err.message}`,
ServerlessErrorCodes.domains.API_GATEWAY_CUSTOM_DOMAIN_FETCH_FAILED,
{ originalMessage: err.message },
)
}
Logging.logWarning(`V1 - '${domain.givenDomainName}' does not exist.`)
}
}
async deleteCustomDomain(domain) {
// Make API call
try {
await this.apiGateway.send(
new DeleteDomainNameCommand({
domainName: domain.givenDomainName,
}),
)
} catch (err) {View on GitHub (pinned to b9d7ea51c8)
Solutions
- Grant apigateway:GET on the domain resource to the deploying role.
- Retry the deploy - throttling and 5xx are typically transient; the SDK retryStrategy may already handle one round but a re-run is the safe fallback.
- If the error is a silent 404 surfacing unexpectedly, audit call sites passing silent=false and pass silent=true where absence is expected.
- Refresh AWS credentials (aws sts get-caller-identity) and confirm the region matches Globals.getRegion().
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm read permission and reachability before the lookup
async function canReadDomain(iam, accountId, region) {
const policy = await iam.simulatePrincipalPolicy({
PolicySourceArn: `arn:aws:iam::${accountId}:role/deploys`,
ActionNames: ['apigateway:GET'],
ResourceArns: [`arn:aws:apigateway:${region}::/domainnames/*`],
})
return policy.EvaluationResults?.[0]?.EvalDecision === 'allowed'
} Try / catch
try {
const info = await wrapper.getCustomDomain(domain, true)
// info is undefined when the domain was a silent 404
} catch (err) {
if (err.code === 'API_GATEWAY_CUSTOM_DOMAIN_FETCH_FAILED') {
const status = err.cause?.$metadata?.httpStatusCode
if (status === 403) throw new Error('deploy role lacks apigateway:GET')
if (status === 429 || status >= 500) { /* retry with backoff */ }
else throw err
} else throw err
} Prevention
- Pass silent=true when absence is an expected state.
- Grant apigateway:GET scoped to /domainnames/* on the deploy role.
- Refresh STS credentials before long-running CI deploys.
- Confirm the deployment region matches the domain's region.
When it happens
Trigger: GetDomainNameCommand returns 403 (missing apigateway:GET), 429 throttling, 5xx service error, or a network failure with no httpStatusCode; or getCustomDomain is invoked with silent=false against a 404.
Common situations: Read-only deployment role lacking apigateway:GET permission; intermittent AWS throttling during a high-volume deploy; cross-account lookup where the assumed role cannot describe the domain; CI running with stale credentials that just expired.
Related errors
- API_GATEWAY_CUSTOM_DOMAIN_CREATION_FAILED
- API_GATEWAY_CUSTOM_DOMAIN_DELETION_FAILED
- API_GATEWAY_CUSTOM_DOMAIN_UPDATE_FAILED
- API_GATEWAY_BASE_PATH_MAPPING_CREATION_FAILED
- API_GATEWAY_BASE_PATH_MAPPING_FETCH_FAILED
AI-assisted analysis of serverless/serverless@b9d7ea51c8 (2026-08-13).
Data as JSON: /api/errors/957209440bb29c8e.
Report an issue: GitHub.