DNS SRV Records: Usage, Format, and Real-World Applications
DNS SRV records are a mechanism for encoding service location information — hostname, port, and load-balancing hints — directly in DNS, without requiring clients to know port numbers in advance or for administrators to publish that information through side channels. They are specified in RFC 2782 and are used by a range of protocols including XMPP, SIP, Matrix, CalDAV, CardDAV, LDAP, and several Microsoft services. This technical note sits within the technical notes section and covers the exact record format, how priority and weight interact to distribute load, how to query SRV records with standard tools, and the configuration mistakes that cause SRV-dependent services to silently fall back to hardcoded defaults. The DNS resolver configuration covered in the Debian DNS resolver guide provides relevant background, and the Windows mDNS and DNS-SD behaviour entry covers the DNS-SD layer that builds on SRV for local service discovery.
The short version
An SRV record has the format _service._proto.name TTL class SRV priority weight port target. A client looking up XMPP for example.com queries _xmpp-client._tcp.example.com and receives one or more SRV records specifying which hosts and ports to connect to. Priority controls failover ordering — lower values are preferred. Weight distributes load across records with equal priority proportionally. The target field must be a hostname with an A or AAAA record; it cannot be an IP address or a CNAME. SRV records only work if the client application implements SRV lookup — many do not, or implement it partially, which is the single most common source of SRV deployment failures.
Record format
An SRV record consists of five fields beyond the standard DNS record header:
_xmpp-client._tcp.example.com. 3600 IN SRV 10 20 5222 xmpp.example.com.
| Field | Value | Meaning |
|---|---|---|
| Name | _xmpp-client._tcp.example.com. | Service _xmpp-client, protocol _tcp, domain example.com |
| TTL | 3600 | Standard DNS TTL in seconds |
| Class | IN | Internet class |
| Priority | 10 | Lower value = higher preference |
| Weight | 20 | Proportional load distribution within same priority |
| Port | 5222 | Port number the service listens on |
| Target | xmpp.example.com. | Hostname to connect to (must have A/AAAA record) |
The name field follows a strict format: _service._proto.domain. The service and protocol components are always prefixed with underscores to distinguish them from regular DNS labels and to avoid collisions with hostnames. Protocol is almost always _tcp or _udp depending on the service.
Priority mechanics
Priority is the primary mechanism for expressing server preference and failover. Clients must attempt to contact the lowest-priority (numerically smallest) server first. Only if that server is unreachable or returns an error should the client proceed to the next priority level.
A simple primary/backup configuration looks like this:
_sip._tcp.example.com. 300 IN SRV 10 0 5060 sip-primary.example.com.
_sip._tcp.example.com. 300 IN SRV 20 0 5060 sip-backup.example.com.
The backup server at priority 20 is only contacted if the primary at priority 10 fails. The weight field is 0 for both because there is only one server at each priority level — weight is only meaningful when multiple records share the same priority.
Weight mechanics and load distribution
When multiple SRV records share the same priority, weight determines how connections are distributed. The client assigns each record a probability proportional to its weight relative to the sum of all weights at that priority level.
_matrix._tcp.example.com. 300 IN SRV 10 60 8448 matrix1.example.com.
_matrix._tcp.example.com. 300 IN SRV 10 40 8448 matrix2.example.com.
In this configuration, 60% of connections go to matrix1 and 40% to matrix2, based on the weight ratio of 60:40. This is probabilistic, not strict round-robin — a client implementing weight correctly chooses from the available records at the same priority using a weighted random selection.
A weight of 0 is a special case: records with weight 0 should be used last among records of the same priority, after all records with non-zero weight have been tried. This is counterintuitive — a weight of 0 does not mean "highest priority among equal-priority records." If you intend equal distribution, use equal non-zero weights (e.g., weight 10 on all records). Using weight 0 on all records of the same priority is valid (clients should select randomly from them), but it is better practice to use explicit equal weights to signal intent clearly.
Real-world protocol usage
SRV records are used across a range of protocols, each defining its own service label:
XMPP (Jabber):
_xmpp-client._tcp— client-to-server connections (port 5222)_xmpp-server._tcp— server-to-server federation (port 5269)
XMPP's SRV usage is one of the oldest and most complete implementations. Clients that support XMPP federation are expected to perform SRV lookup before falling back to the bare domain.
SIP:
_sip._tcp,_sip._udp— standard SIP signalling (port 5060)_sips._tcp— SIP over TLS (port 5061)
SIP SRV records are fundamental to VoIP deployments where multiple servers handle calls and failover needs to be automatic. The SRV TTL in SIP environments is often set low (60–300 seconds) to enable fast failover.
Matrix:
_matrix._tcp— server federation (port 8448)_matrix-fed._tcp— newer federation delegation (also port 8448)
Matrix introduced a .well-known/matrix/server delegation alternative to SRV, but SRV lookup remains the fallback when the well-known endpoint is absent or unreachable.
CalDAV / CardDAV:
_caldavs._tcp,_caldav._tcp— calendar server discovery (ports 8443/8008)_carddavs._tcp,_carddav._tcp— contact server discovery
Apple's Calendar and Contacts applications use these records for automatic account configuration. A correctly published _caldavs._tcp SRV record means users can configure calendar sync by entering only their email address.
LDAP:
_ldap._tcp— directory lookup (port 389)_ldaps._tcp— LDAP over TLS (port 636)
Querying SRV records
Standard DNS tools handle SRV lookups, but the syntax varies:
dig _xmpp-client._tcp.example.com SRV
host -t SRV _xmpp-client._tcp.example.com
Resolve-DnsName -Name _xmpp-client._tcp.example.com -Type SRV
The dig output includes additional section records for the A/AAAA records of the target hostnames, which is useful for verifying that the target resolves correctly. A common debugging scenario is an SRV record that resolves correctly but points to a target hostname that has no corresponding A or AAAA record — the SRV lookup succeeds but the connection fails.
In testing Matrix federation with SRV records, several federation partners were found to publish syntactically correct SRV records but with target hostnames that returned NXDOMAIN. The federation connection failed silently — the sending server logged a DNS lookup success for the SRV record but an immediate failure on the subsequent A record lookup. From the sending side, this is indistinguishable from the receiving server being down. Verifying both the SRV record and the target hostname resolution is a necessary step in federation troubleshooting.
Common pitfalls
SRV targets cannot be CNAME records. RFC 2782 is explicit that the target must be a hostname with a valid A or AAAA record, not an alias. Using a CNAME as an SRV target is technically invalid, and while many resolvers will follow the chain anyway, some clients and resolvers will reject it. Always use the final hostname (the CNAME destination) as the SRV target.
RFC 9461 (published 2023) added the SVCB and HTTPS DNS record types as a more capable alternative to SRV for HTTP-based services. HTTPS records encode TLS parameters, supported protocols (HTTP/2, HTTP/3), and connection hints alongside the service endpoint, reducing round-trips for connection setup. For new HTTP-based service discovery, HTTPS records are the preferred mechanism; SRV remains appropriate for non-HTTP protocols. Client support for SVCB/HTTPS is rolling out across major resolver and browser implementations.
DNS SRV records require client-side implementation — the resolver returns the records, but the application must explicitly query for them and use the results. Many DNS libraries provide SRV lookup as an optional higher-level function rather than implementing it automatically. Before relying on SRV for a service, verify that the specific client application or library actually performs SRV queries. Tools like Wireshark or tcpdump on the DNS port provide unambiguous confirmation of whether SRV lookup is happening in practice.