SRV: service location
*Find the host and* port for a named service.** SRV records let a client discover "where does
_xmpp-server._tcp.example.comlive?" without hard-coding a hostname or port. Used by XMPP, SIP, LDAP, Kerberos, Matrix, and Minecraft.
In one line:
_xmpp-server._tcp.example.com. SRV 10 5 5269 xmpp.example.com.
└── service.protocol.domain ──┘ └type┘ └── priority weight PORT target| Type number | 33 |
| RFC | 2782 |
| RDATA | priority · weight · port · target FQDN |
What it holds#
Four fields:
| Field | Purpose |
|---|---|
| Priority | Lower wins: clients try the record with the lowest priority value first, which is the highest priority. (Same idea as MX preference.) |
| Weight | Within one priority level, weighted random distribution. Higher weight = more traffic. |
| Port | TCP/UDP port the service listens on. |
| Target | A hostname (A/AAAA: NOT a CNAME, just like MX). |
The record name follows a structured form:
_<service>._<proto>.<domain>. SRV <prio> <weight> <port> <target>Examples from the wild:
_xmpp-server._tcp.example.com. SRV 10 5 5269 xmpp.example.com.
_ldap._tcp.example.com. SRV 10 0 389 ldap.example.com.
_kerberos._udp.example.com. SRV 0 0 88 kdc.example.com.
_minecraft._tcp.example.com. SRV 0 0 25565 mc1.example.com.Chat traffic (XMPP) for
example.comruns on port5269of the serverxmpp.example.com: the record names the service, the protocol, the port and the machine, all in one lookup.
When to use it#
- Whenever the service has a registered SRV form (XMPP, SIP, LDAP, Kerberos, autodiscover, Matrix federation, etc.).
- For "service discovery without a load balancer": clients query SRV, get a weighted list of backends.
- For custom in-house services where you want decoupling from a fixed hostname:port.
When not to use it#
- For HTTP/HTTPS: those have their own newer record types (HTTPS/SVCB). Most browsers don't honor SRV for HTTP because of legacy assumptions.
- For services that don't have a registered SRV form and where there's no client support: SRV records the client never reads are dead weight.
dig example#
Asks where the XMPP server for example.isitdns.net lives.
dig @1.1.1.1 _xmpp-server._tcp.example.isitdns.net SRVNOERRORThe server had no complaint about the question.
qrThis message is the answer coming back, not the question going out.
rdYou asked this server to go and find the answer for you.
raThis server says it is willing to go and find answers for you.
adThis server says it checked the signatures, and they held up.
SRVYou asked where a service lives: which host, and which port.
300How many seconds this answer can be reused before asking again. From a cache it is the time left, so it counts down.
Query timeHow long this one lookup took, start to finish.
good: NOERROR and one SRV with priority, weight, port and target
bad: NOERROR with no answer, which means the service is not published here
dig @1.1.1.1 _xmpp-server._tcp.example.isitdns.net SRV +short10 5 5269 example.com.nslookup -type=SRV _xmpp-server._tcp.example.isitdns.net 1.1.1.1Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
_xmpp-server._tcp.example.isitdns.net service = 10 5 5269 example.com.To see the full answer and any additional-section records the resolver chooses to include, use +noall +answer +additional:
dig @1.1.1.1 _xmpp-server._tcp.example.isitdns.net SRV +noall +answer +additional_xmpp-server._tcp.example.isitdns.net. 300 IN SRV 10 5 5269 example.com.nslookup's default output does not show the additional section; it prints only the SRV answer (its
-debugmode dumps every section). Usedig +noall +answer +additionalto expose the additional section if it is present. In practice, resolvers almost never return additional-section A/AAAA records for SRV targets; the additional section above is empty, which is the normal result. The client is expected to follow up with a separate A/AAAA query for the target hostname.
See it live: isitdns.net/#dig?name=_xmpp-server._tcp.example.isitdns.net&qtype=SRV
RFC: RFC 2782 defines SRV: the _service._proto.name form, the four RDATA fields, and the priority-then-weight selection algorithm clients run over the answer.
DoH query (HTTPS)#
DoH is DNS-over-HTTPS. The JSON wire format uses application/dns-json, a Cloudflare/Google extension not defined by RFC 8484 itself:
curl -s -H 'accept: application/dns-json' \
'https://cloudflare-dns.com/dns-query?name=_xmpp-server._tcp.example.isitdns.net&type=SRV' \
| jq .Answer[
{
"name": "_xmpp-server._tcp.example.isitdns.net",
"type": 33,
"TTL": 300,
"data": "10 5 5269 example.com"
}
]The AD field in the full JSON response (not shown by jq .Answer, it appears at the top level) confirms DNSSEC validation passed when true.
nslookup cannot do DoH/DoT/DoQ. On Windows,
Resolve-DnsNameuses the system-configured DoH resolver when the OS is set up for encrypted DNS; there is no DoH parameter, and-Servertakes a classic DNS server IP, not a DoH URL. To probe a specific DoH endpoint, use thecurlform above.
Gotchas#
- Target must be a hostname, not a CNAME (RFC 2782). Most authoritative servers will accept either at creation time, but the target must resolve via A/AAAA for clients to reliably connect.
- Service and proto labels start with underscore.
_ldap, notldap._tcp, nottcp. Easy to miss and silently break discovery. - A target of
.means "no service". RFC 2782 defines a Target of.(the root) as "the service is decidedly not available at this domain". It is the SRV equivalent of null MX: a way to state explicitly that nobody runs this service here, so clients stop looking. - Weight 0 is a special case. Within a given priority level, clients select targets with probability proportional to weight. RFC 2782 says that in the presence of records with weight greater than 0, records with weight 0 should have a very small chance of being selected. Weight 0 is the conventional way to signal "no load-balancing preference" when there is only one target at a priority level, or when equal distribution is fine and you just want valid syntax.
- Browsers do not honor SRV for HTTP. Don't try to express "HTTP at port 8080" as
_http._tcp.example.com SRV: clients won't read it. Use HTTPS/SVCB or just publish the hostname:port out-of-band. - DNSSEC over SRV: SRV records can be signed and validated just like any other, and some protocols require it. XMPP is the SRV case: RFC 7673 builds server-to-server TLS on the
_xmpp-server._tcpSRV lookup, and DANE TLSA records hang off the target it names. SMTP is not: RFC 7672 puts SMTP DANE on the MX RRset, which has to resolve securely, and never touches SRV. The_xmpp-server._tcp.example.isitdns.netdemo record above is signed and validates (a validating resolver returnsAD: trueat the top level of the JSON response).
See also#
- HTTPS/SVCB: the modern SRV-with-hints for web services
- MX: the mail-only ancestor of the same idea, with a preference field but no weight or port
- TLSA/DANE: certificate binding, paired with SRV for XMPP (RFC 7673) and with MX for SMTP (RFC 7672)
- DNSSEC: signing and validating SRV records
- All record types: cheat sheet
- nslookup and dig: command reference for the queries on this page
- Query types: how ANY, SRV, and other qtype requests work