Introduction
Ambassador API Gateway routes traffic to backend services using hostname resolution. When the service hostname cannot be resolved via DNS or Kubernetes service discovery, requests fail with host resolution errors.
Symptoms
Ambassador log error:
```bash $ kubectl logs -n ambassador deployment/ambassador
[ERROR] Failed to resolve hostname 'my-service.default.svc.cluster.local': No such host is known [ERROR] DNS resolution failed for upstream ```
Mapping error:
```yaml # Ambassador diagnostic ambassador diag show mapping # Error: Unable to resolve service host
# HTTP 503 returned to client HTTP/1.1 503 Service Unavailable upstream connect error or disconnect/reset before headers ```
Common Causes
- 1.Service doesn't exist - Kubernetes service not created
- 2.Wrong namespace - Service in different namespace
- 3.DNS misconfiguration - CoreDNS issues
- 4.Service name typo - Incorrect service name in mapping
- 5.Service not ready - Service exists but no endpoints
- 6.External DNS issue - External hostname unreachable
Step-by-Step Fix
Step 1: Check Ambassador Logs
```bash # Check Ambassador pod logs kubectl logs -n ambassador deployment/ambassador | grep -i "resolve|dns|host"
# Check for specific error kubectl logs -n ambassador deployment/ambassador | grep "my-service"
# View recent errors kubectl logs -n ambassador deployment/ambassador --tail=100 | grep ERROR
# Check Envoy logs kubectl logs -n ambassador deployment/ambassador -c istio-proxy
# Get Ambassador diagnostics kubectl exec -n ambassador deployment/ambassador -- ambassador diag show mappings ```
Step 2: Verify Kubernetes Service Exists
```bash # Check if service exists kubectl get svc -A | grep my-service
# Check service in specific namespace kubectl get svc my-service -n default
# Get service details kubectl describe svc my-service -n default
# Check service ClusterIP kubectl get svc my-service -n default -o jsonpath='{.spec.clusterIP}'
# If service doesn't exist, create it: kubectl expose deployment my-deployment --port=8080 --target-port=80 --name=my-service ```
Step 3: Check Ambassador Mapping
```yaml # Check existing mappings kubectl get mappings -A
# Describe specific mapping kubectl describe mapping my-mapping -n default
# Example correct mapping: apiVersion: getambassador.io/v3alpha1 kind: Mapping metadata: name: my-mapping namespace: default spec: hostname: "api.example.com" prefix: /api/ service: my-service.default:8080 # namespace.service:port # For cross-namespace: service.namespace.svc.cluster.local:port ```
Step 4: Fix Service Reference in Mapping
```yaml # WRONG: Missing namespace for cross-namespace reference spec: service: my-service # Only works if in same namespace as Ambassador
# CORRECT: Include namespace spec: service: my-service.default # namespace.service
# CORRECT: Full FQDN spec: service: my-service.default.svc.cluster.local:8080
# CORRECT: External service spec: service: https://external-api.example.com
# Apply mapping kubectl apply -f mapping.yaml ```
Step 5: Test DNS Resolution
```bash # Test DNS from Ambassador pod kubectl exec -n ambassador deployment/ambassador -- nslookup my-service.default
# Test from test pod kubectl run dns-test --image=busybox --rm -it -- nslookup my-service.default.svc.cluster.local
# Check CoreDNS kubectl get pods -n kube-system -l k8s-app=kube-dns
# Check CoreDNS logs kubectl logs -n kube-system -l k8s-app=kube-dns
# Test DNS resolution kubectl exec -n ambassador deployment/ambassador -- dig my-service.default.svc.cluster.local
# Check /etc/resolv.conf kubectl exec -n ambassador deployment/ambassador -- cat /etc/resolv.conf ```
Step 6: Check Service Endpoints
```bash # Check endpoints exist kubectl get endpoints my-service -n default
# Describe endpoints kubectl describe endpoints my-service -n default
# If no endpoints, check pod labels match service selector kubectl get pods -n default -l app=my-app
# Check service selector kubectl get svc my-service -n default -o jsonpath='{.spec.selector}'
# Check pod labels kubectl get pods -n default -o wide --show-labels
# If selector mismatch, fix service or pod labels kubectl patch svc my-service -n default -p '{"spec":{"selector":{"app":"my-app"}}}' ```
Step 7: Check Ambassador Configuration
```bash # View Ambassador configuration kubectl exec -n ambassador deployment/ambassador -- ambassador diag show config
# Check Module configuration kubectl get modules -A
# Check Ambassador installation kubectl get all -n ambassador
# Verify Ambassador version kubectl exec -n ambassador deployment/ambassador -- ambassador --version
# Check Ambassador is receiving config kubectl exec -n ambassador deployment/ambassador -- ambassador diag show all ```
Step 8: Check Cross-Namespace Access
```bash # Ambassador typically runs in 'ambassador' namespace # Services may be in different namespaces
# List all namespaces kubectl get namespaces
# Check service in target namespace kubectl get svc -n production
# Mapping must include namespace: # service: my-service.production:8080
# If using service.namespace format: spec: service: my-service.production:8080
# If using FQDN: spec: service: my-service.production.svc.cluster.local:8080 ```
Step 9: Handle External Services
```yaml # For external services, use full URL apiVersion: getambassador.io/v3alpha1 kind: Mapping metadata: name: external-api spec: hostname: "api.example.com" prefix: /external/ service: https://external-api.example.com # Add timeout for external services timeout_ms: 30000
# For external services with custom DNS spec: service: https://192.168.1.100:8443 tls: upstream-tls-context
# Create TLS context if needed apiVersion: getambassador.io/v3alpha1 kind: TLSContext metadata: name: upstream-tls-context spec: hosts: ["*"] secret: upstream-tls-secret ```
Step 10: Reload Ambassador Configuration
```bash # Force Ambassador to reload configuration kubectl rollout restart deployment/ambassador -n ambassador
# Or delete pod to force restart kubectl delete pod -n ambassador -l app=ambassador
# Wait for pod to be ready kubectl rollout status deployment/ambassador -n ambassador
# Check new pod is running kubectl get pods -n ambassador
# Verify configuration loaded kubectl exec -n ambassador deployment/ambassador -- ambassador diag show mappings ```
Ambassador Service Resolution Patterns
| Service Type | Format | Example |
|---|---|---|
| Same namespace | service:port | my-service:8080 |
| Cross namespace | service.namespace:port | api.production:80 |
| Full FQDN | service.namespace.svc.cluster.local:port | api.prod.svc.cluster.local:80 |
| External HTTP | http://host:port | http://api.example.com:8080 |
| External HTTPS | https://host | https://api.example.com |
Verification
```bash # After fixing mapping
# 1. Verify service exists kubectl get svc my-service -n default
# 2. Verify endpoints exist kubectl get endpoints my-service -n default
# 3. Test DNS from Ambassador kubectl exec -n ambassador deployment/ambassador -- nslookup my-service.default
# 4. Check mapping is valid kubectl exec -n ambassador deployment/ambassador -- ambassador diag show mapping my-mapping
# 5. Test the route curl -H "Host: api.example.com" http://AMBASSADOR_IP/api/
# Should return 200, not 503
# 6. Check Ambassador logs for success kubectl logs -n ambassador deployment/ambassador --tail=20 | grep -v ERROR ```
Prevention
To prevent Ambassador host resolution issues from recurring, implement these proactive measures:
1. Monitor Ambassador Health
groups:
- name: ambassador-health
rules:
- alert: AmbassadorHostResolutionFailed
expr: |
ambassador_host_resolution_failures > 0
for: 2m
labels:
severity: warning
annotations:
summary: "Ambassador host resolution failures detected"2. Configure Service Health Checks
# Kubernetes service with proper health check
apiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
getambassador.io/config: |
---
apiVersion: ambassador/v2
kind: Mapping
name: my-mapping
host: api.example.com
prefix: /api/
service: my-service.default:8080
connect_timeout_ms: 3000
idle_timeout_ms: 60000
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 80803. Test Service Discovery
```bash # Regular DNS resolution test kubectl exec -n ambassador deployment/ambassador -- nslookup my-service.default.svc.cluster.local
# Alert on DNS failures ```
Best Practices Checklist
- [ ] Monitor Ambassador resolution failures
- [ ] Configure health checks for services
- [ ] Test service discovery regularly
- [ ] Use proper Kubernetes DNS names
- [ ] Document service naming conventions
- [ ] Set appropriate timeouts
Related Issues
- [Fix Kubernetes Service Endpoints Empty](/articles/fix-kubernetes-service-endpoints-empty)
- [Fix Ambassador TLS Certificate Error](/articles/fix-ambassador-tls-certificate-error)
- [Fix Kubernetes DNS Resolution Failed](/articles/fix-kubernetes-dns-resolution-failed)
Related Articles
- [Technical troubleshooting: Fix Certificate Chain Incomplete SSL Validation Is](certificate-chain-incomplete-ssl-validation)
- [Fix Ddos Attack Mitigation Waf Rate Limiting Issue in Network Security](ddos-attack-mitigation-waf-rate-limiting)
- [Fix DNS Hijacking Spoofing Attack Issue in Network Security](dns-hijacking-spoofing-attack)
- [Fix firewall iptables rules not persisting across reboot Issue in Network-Security](firewall-iptables-rules-not-persisting-across-reboot)
- [Fix firewall rule blocking legitimate traffic Issue in Network-Security](firewall-rule-blocking-legitimate-traffic)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Ambassador Host Resolution Failed", "description": "Troubleshoot Ambassador host resolution failures. Check DNS, service discovery, and mapping configuration.", "url": "https://www.fixwikihub.com/fix-ambassador-host-resolution-failed", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-03T23:54:27.593Z", "dateModified": "2026-04-03T23:54:27.593Z" } </script>