MX Records (Mail Exchange)
MX records specify the mail servers responsible for accepting email on behalf of a domain. Each MX record includes a priority value that determines the order in which mail servers are contacted.
Creating an MX Record
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mail-example
namespace: dns-system
spec:
zoneRef: example-com # References DNSZone metadata.name (recommended)
name: "@" # Zone apex - mail for @example.com
priority: 10
mailServer: mail.example.com. # Must end with a dot (FQDN)
ttl: 3600
This configures mail delivery for example.com to mail.example.com with priority 10.
Note: You can also use zone: example.com (matching DNSZone.spec.zoneName) instead of zoneRef. See Referencing DNS Zones for details on choosing between zone and zoneRef.
FQDN Requirement
CRITICAL: The mailServer field MUST end with a dot (.) to indicate a fully qualified domain name (FQDN).
# ✅ CORRECT
mailServer: mail.example.com.
# ❌ WRONG - will be treated as relative to zone
mailServer: mail.example.com
Priority Values
Lower priority values are preferred. Mail servers with the lowest priority are contacted first.
Single Mail Server
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-primary
spec:
zoneRef: example-com
name: "@"
priority: 10
mailServer: mail.example.com.
Multiple Mail Servers (Failover)
# Primary mail server (lowest priority)
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-primary
spec:
zoneRef: example-com
name: "@"
priority: 10
mailServer: mail1.example.com.
ttl: 3600
---
# Backup mail server
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-backup
spec:
zoneRef: example-com
name: "@"
priority: 20
mailServer: mail2.example.com.
ttl: 3600
Sending servers will try mail1.example.com first (priority 10), falling back to mail2.example.com (priority 20) if the primary is unavailable.
Load Balancing
Equal priority values enable round-robin load balancing:
# Server 1
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-1
spec:
zoneRef: example-com
name: "@"
priority: 10
mailServer: mail1.example.com.
---
# Server 2 (same priority)
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-2
spec:
zoneRef: example-com
name: "@"
priority: 10
mailServer: mail2.example.com.
Both servers share the load equally.
Subdomain Mail
Configure mail for a subdomain:
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: support-mail
spec:
zoneRef: example-com
name: support # Email: user@support.example.com
priority: 10
mailServer: mail-support.example.com.
Common Configurations
Google Workspace (formerly G Suite)
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-google-1
spec:
zoneRef: example-com
name: "@"
priority: 1
mailServer: aspmx.l.google.com.
ttl: 3600
---
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-google-2
spec:
zoneRef: example-com
name: "@"
priority: 5
mailServer: alt1.aspmx.l.google.com.
---
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-google-3
spec:
zoneRef: example-com
name: "@"
priority: 5
mailServer: alt2.aspmx.l.google.com.
---
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-google-4
spec:
zoneRef: example-com
name: "@"
priority: 10
mailServer: alt3.aspmx.l.google.com.
---
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-google-5
spec:
zoneRef: example-com
name: "@"
priority: 10
mailServer: alt4.aspmx.l.google.com.
Microsoft 365
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-microsoft
spec:
zoneRef: example-com
name: "@"
priority: 0
mailServer: example-com.mail.protection.outlook.com. # Replace 'example-com' with your domain
ttl: 3600
Self-Hosted Mail Server
# Primary MX
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-primary
spec:
zoneRef: example-com
name: "@"
priority: 10
mailServer: mail.example.com.
---
# Corresponding A record for mail server
apiVersion: bindy.firestoned.io/v1alpha1
kind: ARecord
metadata:
name: mail-server
spec:
zoneRef: example-com
name: mail
ipv4Address: "203.0.113.10"
Best Practices
- Always use FQDNs - End
mailServervalues with a dot (.) - Set appropriate TTLs - Use longer TTLs (3600-86400) for stable mail configurations
- Configure backups - Use multiple MX records with different priorities for redundancy
- Test mail delivery - Verify mail flow after DNS changes
- Coordinate with SPF/DKIM - Update TXT records when adding mail servers
Required Supporting Records
MX records need corresponding A/AAAA records for the mail servers:
# MX record points to mail.example.com
apiVersion: bindy.firestoned.io/v1alpha1
kind: MXRecord
metadata:
name: mx-main
spec:
zoneRef: example-com
name: "@"
priority: 10
mailServer: mail.example.com.
---
# A record for mail.example.com
apiVersion: bindy.firestoned.io/v1alpha1
kind: ARecord
metadata:
name: mail-server-ipv4
spec:
zoneRef: example-com
name: mail
ipv4Address: "203.0.113.10"
---
# AAAA record for IPv6
apiVersion: bindy.firestoned.io/v1alpha1
kind: AAAARecord
metadata:
name: mail-server-ipv6
spec:
zoneRef: example-com
name: mail
ipv6Address: "2001:db8::10"
Status Monitoring
Check the status of your MX record:
kubectl get mxrecord mx-primary -o yaml
Look for the status.conditions field:
status:
conditions:
- type: Ready
status: "True"
reason: ReconcileSucceeded
message: "Record configured on 3 endpoint(s)"
lastTransitionTime: "2024-11-26T10:00:01Z"
observedGeneration: 1
Troubleshooting
Mail not being delivered
-
Check MX record status:
kubectl get mxrecord mx-primary -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' -
Verify DNS propagation:
dig MX example.com @<dns-server-ip> -
Test from external servers:
nslookup -type=MX example.com 8.8.8.8 -
Check mail server A/AAAA records exist:
dig A mail.example.com
Common Mistakes
- Missing trailing dot -
mail.example.cominstead ofmail.example.com. - No A/AAAA record - MX points to a hostname that doesn’t resolve
- Wrong priority - Higher priority when you meant lower (remember: lower = preferred)
- Relative vs absolute - Without trailing dot, name is treated as relative to zone
Testing Mail Configuration
Test MX lookup
# Query MX records
dig MX example.com
# Expected output shows priority and mail server
;; ANSWER SECTION:
example.com. 3600 IN MX 10 mail.example.com.
example.com. 3600 IN MX 20 mail2.example.com.
Test mail server connectivity
# Test SMTP connection
telnet mail.example.com 25
# Or using openssl for TLS
openssl s_client -starttls smtp -connect mail.example.com:25
Next Steps
- TXT Records - Configure SPF, DKIM, DMARC for mail authentication
- A Records - Create A records for mail servers
- DNS Records Overview - Complete guide to all record types
- Monitoring DNS - Monitor your DNS infrastructure