Managing MX Record Priorities
MX record priorities determine the order in which mail servers are contacted for email delivery. Understanding how to monitor priorities ensures your email infrastructure maintains proper routing configuration.
Understanding MX Priorities
MX records consist of two parts:
- Priority (preference value): Lower numbers indicate higher priority
- Hostname: The mail server address
Example MX records:
10 mx1.mail-provider.com ← Primary (highest priority)
20 mx2.mail-provider.com ← Secondary
30 mx3.mail-provider.com ← Backup (lowest priority)
Email servers attempt delivery to the lowest priority number first, falling back to higher numbers if delivery fails.
Monitoring Without Priorities
By default, if you don't specify priorities, DNSRadar accepts any priority value:
curl -X POST https://api.dnsradar.dev/monitors \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"mx1.mail-provider.com",
"mx2.mail-provider.com"
]
}'const response = await fetch('https://api.dnsradar.dev/monitors', {
method: 'POST',
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"mx1.mail-provider.com",
"mx2.mail-provider.com"
]
})
});
const data = await response.json();import requests
response = requests.post(
'https://api.dnsradar.dev/monitors',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"mx1.mail-provider.com",
"mx2.mail-provider.com"
]
}
)require 'net/http'
require 'json'
uri = URI('https://api.dnsradar.dev/monitors')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = 'YOUR_API_KEY'
request['Content-Type'] = 'application/json'
request.body = {
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"mx1.mail-provider.com",
"mx2.mail-provider.com"
]
}.to_json
response = http.request(request)package main
import (
"bytes"
"encoding/json"
"net/http"
)
data := {
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"mx1.mail-provider.com",
"mx2.mail-provider.com"
]
}
jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.dnsradar.dev/monitors", bytes.NewBuffer(jsonData))
req.Header.Set("X-API-Key", "YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
response, _ := client.Do(req)<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.dnsradar.dev/monitors');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
$headers = [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = json_encode({
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"mx1.mail-provider.com",
"mx2.mail-provider.com"
]
});
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """{
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"mx1.mail-provider.com",
"mx2.mail-provider.com"
]
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.dnsradar.dev/monitors"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());using System.Net.Http;
using System.Text;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var data = new
{
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"mx1.mail-provider.com",
"mx2.mail-provider.com"
]
};
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://api.dnsradar.dev/monitors",
content
);This configuration matches ANY of these:
10 mx1.mail-provider.com, 20 mx2.mail-provider.com ✅
5 mx1.mail-provider.com, 10 mx2.mail-provider.com ✅
100 mx1.mail-provider.com, 100 mx2.mail-provider.com ✅
50 mx1.mail-provider.com, 40 mx2.mail-provider.com ✅
Priority Flexibility: Omitting priorities is useful when you care only that specific mail servers are configured, not their preference order.
Monitoring With Priorities
To enforce specific priorities, include them in your expected values using the format "<priority> <hostname>":
curl -X POST https://api.dnsradar.dev/monitors \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.mail-provider.com",
"20 mx2.mail-provider.com"
]
}'const response = await fetch('https://api.dnsradar.dev/monitors', {
method: 'POST',
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.mail-provider.com",
"20 mx2.mail-provider.com"
]
})
});
const data = await response.json();import requests
response = requests.post(
'https://api.dnsradar.dev/monitors',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.mail-provider.com",
"20 mx2.mail-provider.com"
]
}
)require 'net/http'
require 'json'
uri = URI('https://api.dnsradar.dev/monitors')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = 'YOUR_API_KEY'
request['Content-Type'] = 'application/json'
request.body = {
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.mail-provider.com",
"20 mx2.mail-provider.com"
]
}.to_json
response = http.request(request)package main
import (
"bytes"
"encoding/json"
"net/http"
)
data := {
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.mail-provider.com",
"20 mx2.mail-provider.com"
]
}
jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.dnsradar.dev/monitors", bytes.NewBuffer(jsonData))
req.Header.Set("X-API-Key", "YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
response, _ := client.Do(req)<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.dnsradar.dev/monitors');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
$headers = [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = json_encode({
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.mail-provider.com",
"20 mx2.mail-provider.com"
]
});
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """{
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.mail-provider.com",
"20 mx2.mail-provider.com"
]
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.dnsradar.dev/monitors"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());using System.Net.Http;
using System.Text;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var data = new
{
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.mail-provider.com",
"20 mx2.mail-provider.com"
]
};
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://api.dnsradar.dev/monitors",
content
);This configuration ONLY matches:
10 mx1.mail-provider.com, 20 mx2.mail-provider.com ✅
These would trigger MISMATCH:
5 mx1.mail-provider.com, 20 mx2.mail-provider.com ❌ Wrong priority for mx1
10 mx1.mail-provider.com, 30 mx2.mail-provider.com ❌ Wrong priority for mx2
20 mx1.mail-provider.com, 10 mx2.mail-provider.com ❌ Priorities reversed
Priority Format Rules
Format Requirements:
- Priority must be the first element
- Separate priority and hostname with a single space
- Priority must be a positive integer (0-65535)
- Format:
"<priority> <hostname>"
Valid Formats
{
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com",
"30 mx3.service.com"
]
}
Invalid Formats
{
"expected_value": [
"mx1.service.com 10", // ❌ Priority must be first
"10mx1.service.com", // ❌ Missing space
"10 mx1.service.com", // ❌ Multiple spaces
"10. mx1.service.com" // ❌ Invalid priority format
]
}
Consistency Requirements
All or Nothing: You must be consistent within each monitor. Either specify priorities for all MX records or for none. Mixing causes validation errors.
Invalid (Mixed)
{
"expected_value": [
"10 mx1.service.com", // With priority
"mx2.service.com" // Without priority
]
// ❌ INVALID: Inconsistent format
}
Valid (Consistent)
// All without priorities ✅
{
"expected_value": [
"mx1.service.com",
"mx2.service.com"
]
}
// All with priorities ✅
{
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com"
]
}
Priorities with Flexible Matching
You can combine priority enforcement with flexible matching to allow additional mail servers:
curl -X POST https://api.dnsradar.dev/monitors \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com"
],
"is_exact_match": false
}'const response = await fetch('https://api.dnsradar.dev/monitors', {
method: 'POST',
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com"
],
"is_exact_match": false
})
});
const data = await response.json();import requests
response = requests.post(
'https://api.dnsradar.dev/monitors',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com"
],
"is_exact_match": false
}
)require 'net/http'
require 'json'
uri = URI('https://api.dnsradar.dev/monitors')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = 'YOUR_API_KEY'
request['Content-Type'] = 'application/json'
request.body = {
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com"
],
"is_exact_match": false
}.to_json
response = http.request(request)package main
import (
"bytes"
"encoding/json"
"net/http"
)
data := {
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com"
],
"is_exact_match": false
}
jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.dnsradar.dev/monitors", bytes.NewBuffer(jsonData))
req.Header.Set("X-API-Key", "YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
response, _ := client.Do(req)<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.dnsradar.dev/monitors');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
$headers = [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = json_encode({
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com"
],
"is_exact_match": false
});
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """{
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com"
],
"is_exact_match": false
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.dnsradar.dev/monitors"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());using System.Net.Http;
using System.Text;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var data = new
{
"domain": "piedpiper.com",
"record_type": "MX",
"expected_value": [
"10 mx1.service.com",
"20 mx2.service.com"
],
"is_exact_match": false
};
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://api.dnsradar.dev/monitors",
content
);This configuration:
- ✅ Enforces specific priorities for your mail servers
- ✅ Allows customers to add additional mail servers at any priority
- ❌ Triggers
MISMATCHif your servers' priorities change
Example valid configurations:
10 mx1.service.com, 20 mx2.service.com ✅
10 mx1.service.com, 20 mx2.service.com, 30 mx.backup.com ✅
10 mx1.service.com, 15 mx.other.com, 20 mx2.service.com ✅
5 mx.customer.com, 10 mx1.service.com, 20 mx2.service.com ✅
When Priorities Don't Matter
Skip priority monitoring when:
- Service Provider Changes: Email providers may adjust priorities for optimization
- Customer Flexibility: Customers should control their mail routing preferences
- Equal Priority Load Balancing: When multiple servers share the same priority
- Backup Server Addition: Customers adding their own backup servers