API Gateway Troubleshooting Guide
Problem: 404 Errors on API Routes
If you're getting 404 errors on https://api.hashpass.tech/api/*, it means API Gateway is not configured correctly or the Lambda function is not deployed.
⚠️ CRITICAL: DNS Configuration Issue
Current Status: api.hashpass.tech is pointing to Amplify Hosting (CloudFront/S3), NOT API Gateway.
Evidence:
- DNS resolves to AWS CloudFront IPs (18.155.252.x)
- HTTP response shows
server: AmazonS3andvia: CloudFront - Returns 301 redirects instead of API responses
Solution: You need to either:
- Change DNS to point to API Gateway (if API Gateway is configured)
- Configure API Gateway and update DNS (if not configured yet)
- Use a different subdomain for API Gateway (e.g.,
api-gateway.hashpass.tech)
Quick Checklist
1. Verify API Gateway Exists
- Go to AWS API Gateway Console
- Check if there's an API named
hashpassApior similar - Verify it has routes configured for
/api/*
2. Verify Lambda Function is Deployed
- Go to AWS Lambda Console
- Check if function
bslApior similar exists - Verify it's deployed and has the latest code
- Check CloudWatch logs for errors
3. Verify Custom Domain Configuration
- In API Gateway Console → Custom Domain Names
- Check if
api.hashpass.techis configured - Verify domain status is "Available"
- Check that the API mapping is configured
4. Verify DNS Configuration
- Check Route 53 or your DNS provider
- Verify
api.hashpass.techhas a CNAME or A record - Should point to API Gateway's domain (not Amplify Hosting)
Step-by-Step Configuration
Step 1: Create/Update Lambda Function
-
Go to AWS Lambda Console
-
Create or update function
bslApi:- Runtime: Node.js 18.x or 20.x
- Handler:
index.handlerorhandler.handler - Timeout: 30 seconds (or more)
- Memory: 512 MB (or more)
-
Upload the function code:
- The function should be in
amplify-backend-config/backend/function/bslApi/ - Or use the handler from
amplify/function-handler.js
- The function should be in
Step 2: Configure API Gateway
-
Create REST API:
- Go to API Gateway Console
- Create new REST API or use existing
- Name:
hashpassApi
-
Create Resource:
- Create resource
/api - Create resource
/api/{proxy+}(catch-all for all API routes)
- Create resource
-
Create Method:
- Select
ANYmethod on/api/{proxy+} - Integration type: Lambda Function
- Select your Lambda function
- Enable "Use Lambda Proxy integration"
- Select
-
Deploy API:
- Create new stage (e.g.,
prodordev) - Note the Invoke URL
- Create new stage (e.g.,
Step 3: Configure Custom Domain
-
In API Gateway Console → Custom Domain Names:
- Click "Create"
- Domain name:
api.hashpass.tech - Certificate: Select ACM certificate for
*.hashpass.techorhashpass.tech - Click "Create domain name"
-
Configure API Mapping:
- Click on the domain name
- Click "API mappings" → "Configure API mappings"
- Add mapping:
- API: Select your API
- Stage: Select your stage (e.g.,
prod) - Path: (leave empty for root)
- Save
-
Get Target Domain:
- Note the "API Gateway domain name" (e.g.,
d-xxxxx.execute-api.us-east-1.amazonaws.com)
- Note the "API Gateway domain name" (e.g.,
Step 4: Configure DNS
-
In Route 53 or your DNS provider:
- Create CNAME record:
- Name:
api - Type:
CNAME - Value: API Gateway domain name from Step 3
- TTL: 300
- Name:
- Create CNAME record:
-
Wait for DNS propagation (can take up to 48 hours, usually much faster)
Step 5: Test
-
Test API Gateway directly:
curl https://YOUR-API-ID.execute-api.REGION.amazonaws.com/prod/api/config/versions -
Test custom domain:
curl https://api.hashpass.tech/api/config/versions
Lambda Function Handler
The Lambda function should use Expo Server to handle API routes. Here's a basic handler:
const { createRequestHandler } = require('@expo/server/adapter/node');
const handler = createRequestHandler({
build: require('path').join(__dirname, 'server'),
});
exports.handler = async (event) => {
try {
// Convert API Gateway event to Request
const request = new Request(
`https://${event.requestContext.domainName}${event.path}${event.rawQueryString ? `?${event.rawQueryString}` : ''}`,
{
method: event.httpMethod,
headers: new Headers(event.headers || {}),
body: event.body ? event.body : undefined,
}
);
// Handle with Expo Server
const response = await handler(request);
const body = await response.text();
const headers = {};
response.headers.forEach((value, key) => {
headers[key] = value;
});
return {
statusCode: response.status,
headers: {
...headers,
'Access-Control-Allow-Origin': '*',
},
body,
};
} catch (error) {
console.error('Error:', error);
return {
statusCode: 500,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({ error: error.message }),
};
}
};
Common Issues
Issue: 404 Not Found
Causes:
- API Gateway route not configured
- Lambda function not deployed
- Custom domain not mapped to API
Solutions:
- Verify API Gateway has
/api/{proxy+}route - Check Lambda function exists and is deployed
- Verify custom domain API mapping
Issue: 502 Bad Gateway
Causes:
- Lambda function error
- Lambda timeout
- Lambda not returning correct format
Solutions:
- Check CloudWatch logs for Lambda errors
- Increase Lambda timeout
- Verify Lambda returns correct API Gateway format
Issue: CORS Errors
Causes:
- Missing CORS headers in Lambda response
- API Gateway CORS not configured
Solutions:
- Add CORS headers in Lambda response (see handler above)
- Configure CORS in API Gateway if needed
Issue: DNS Not Resolving
Causes:
- DNS record not created
- DNS propagation delay
- Wrong DNS record type
Solutions:
- Verify CNAME record exists in Route 53
- Wait for DNS propagation (use
dig api.hashpass.techto check) - Ensure using CNAME, not A record
Verification Commands
# Check DNS resolution
dig api.hashpass.tech
nslookup api.hashpass.tech
# Test API Gateway directly (replace with your API ID and region)
curl https://YOUR-API-ID.execute-api.us-east-1.amazonaws.com/prod/api/config/versions
# Test custom domain
curl https://api.hashpass.tech/api/config/versions
Next Steps
- Verify all steps above are completed
- Check CloudWatch logs for any errors
- Test the endpoint with curl or Postman
- If still not working, check API Gateway logs and Lambda logs