Every time you register a domain, renew it, transfer it, or update its nameservers, a protocol called EPP carries that action from your registrar to the registry. EPP is the invisible plumbing of the domain registration system — unseen by end users but essential to every operation in the domain ecosystem.
Understanding EPP gives you a view behind the curtain: what actually happens when you click “Register,” how status codes control your domain’s behavior, and why certain operations take the time they do.
What is EPP?
The Extensible Provisioning Protocol is an XML-based client-server protocol designed for provisioning and managing objects stored in a shared central repository — in practice, domain names, contacts, and hosts (nameservers) in a registry database.
EPP was developed by the IETF and is defined across several RFCs:
| RFC | Title | Purpose |
|---|---|---|
| RFC 5730 | EPP | Core protocol framework |
| RFC 5731 | EPP Domain Name Mapping | Domain-specific commands |
| RFC 5732 | EPP Host Mapping | Nameserver object commands |
| RFC 5733 | EPP Contact Mapping | Contact object commands |
| RFC 5734 | EPP Transport over TCP | Network transport specification |
EPP replaced earlier, registry-specific protocols (like the RRP — Registry Registrar Protocol used by Verisign) with a standardized system that works across all ICANN-accredited registries.
Architecture
EPP uses a client-server model over persistent TCP connections with TLS encryption:
┌──────────────┐ TLS/TCP ┌──────────────┐
│ Registrar │◄───────────────────────►│ Registry │
│ (EPP Client)│ Port 700 (standard) │ (EPP Server) │
└──────────────┘ └──────────────┘
Key architectural features:
- Persistent connections: Unlike HTTP (traditionally), EPP maintains long-lived TCP connections. A registrar opens a session, authenticates, and sends commands over that session.
- Synchronous request-response: Each command gets exactly one response. No streaming, no callbacks.
- Stateful sessions: After login, the server tracks the client’s authentication state.
- XML-based: All messages are well-formed XML documents with strict schema validation.
The Session Lifecycle
An EPP session follows a fixed pattern:
1. Greeting
When a client connects, the server immediately sends a <greeting> containing:
- Server name and version
- Supported protocol versions
- Supported languages
- Supported object types and extensions
- Data collection policy
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<greeting>
<svID>Example Registry EPP Server</svID>
<svDate>2024-01-15T00:00:00Z</svDate>
<svcMenu>
<version>1.0</version>
<lang>en</lang>
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
</svcMenu>
</greeting>
</epp>
2. Login
The client authenticates with credentials:
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<login>
<clID>RegistrarX</clID>
<pw>secretPassword123</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
</svcs>
</login>
</command>
</epp>
3. Commands
After login, the client sends commands and receives responses (the bulk of the session).
4. Logout
The client terminates the session gracefully:
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<logout/>
</command>
</epp>
EPP Commands
EPP defines a set of standard commands for managing domain objects:
Query Commands
<check> — Test whether a domain is available for registration:
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.com</domain:name>
<domain:name>example.net</domain:name>
</domain:check>
Response indicates availability:
<domain:chkData>
<domain:cd>
<domain:name avail="0">example.com</domain:name>
<domain:reason>In use</domain:reason>
</domain:cd>
<domain:cd>
<domain:name avail="1">example.net</domain:name>
</domain:cd>
</domain:chkData>
<info> — Retrieve detailed information about a domain:
<domain:info xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name hosts="all">example.com</domain:name>
<domain:authInfo>
<domain:pw>authSecret123</domain:pw>
</domain:authInfo>
</domain:info>
The response includes registrant, contacts, nameservers, status codes, dates, and auth info (if the querier is the sponsoring registrar).
Transform Commands
<create> — Register a new domain:
<domain:create xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>newdomain.com</domain:name>
<domain:period unit="y">2</domain:period>
<domain:ns>
<domain:hostObj>ns1.example.com</domain:hostObj>
<domain:hostObj>ns2.example.com</domain:hostObj>
</domain:ns>
<domain:registrant>contact-123</domain:registrant>
<domain:contact type="admin">contact-456</domain:contact>
<domain:contact type="tech">contact-789</domain:contact>
<domain:authInfo>
<domain:pw>newAuthCode!@#</domain:pw>
</domain:authInfo>
</domain:create>
<update> — Modify domain properties (nameservers, contacts, status):
<domain:update xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.com</domain:name>
<domain:add>
<domain:ns>
<domain:hostObj>ns3.example.com</domain:hostObj>
</domain:ns>
<domain:status s="clientTransferProhibited"/>
</domain:add>
<domain:rem>
<domain:ns>
<domain:hostObj>ns1.old-provider.com</domain:hostObj>
</domain:ns>
</domain:rem>
</domain:update>
<delete> — Remove a domain from the registry:
<domain:delete xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.com</domain:name>
</domain:delete>
<renew> — Extend the domain’s registration period:
<domain:renew xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.com</domain:name>
<domain:curExpDate>2025-04-03</domain:curExpDate>
<domain:period unit="y">1</domain:period>
</domain:renew>
The curExpDate is a safety check — it must match the registry’s current expiry date, preventing accidental double-renewals.
<transfer> — Request, approve, reject, or cancel a domain transfer:
<domain:transfer op="request"
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.com</domain:name>
<domain:authInfo>
<domain:pw>authFromCurrentOwner</domain:pw>
</domain:authInfo>
</domain:transfer>
The op attribute specifies the operation: request, approve, reject, cancel, or query. For the full transfer workflow from a registrant’s perspective, see Domain Transfers.
EPP Status Codes
Status codes are one of EPP’s most important features. They control what operations are allowed on a domain and indicate its current lifecycle state. Status codes come in two varieties:
Client Status Codes
Set by the registrar (the “client” in EPP terminology):
| Code | Meaning |
|---|---|
clientDeleteProhibited |
Registrar prevents deletion |
clientHold |
Registrar suspends DNS resolution |
clientRenewProhibited |
Registrar prevents renewal |
clientTransferProhibited |
Registrar prevents transfer (the “registrar lock”) |
clientUpdateProhibited |
Registrar prevents modifications |
Server Status Codes
Set by the registry (the “server”):
| Code | Meaning |
|---|---|
serverDeleteProhibited |
Registry prevents deletion |
serverHold |
Registry suspends DNS resolution |
serverRenewProhibited |
Registry prevents renewal |
serverTransferProhibited |
Registry prevents transfer |
serverUpdateProhibited |
Registry prevents modifications |
Lifecycle Status Codes
| Code | Meaning |
|---|---|
ok |
Normal, active — no pending operations or prohibitions |
addPeriod |
Within the Add Grace Period after registration |
autoRenewPeriod |
Within the Auto-Renew Grace Period |
renewPeriod |
Within the Renew Grace Period |
transferPeriod |
Within the Transfer Grace Period |
redemptionPeriod |
Domain deleted, in redemption (recoverable at high cost) |
pendingCreate |
Registration is pending |
pendingDelete |
Domain queued for deletion (5-day countdown) |
pendingRenew |
Renewal is pending |
pendingRestore |
Restoration from redemption is pending |
pendingTransfer |
Transfer is in progress |
pendingUpdate |
Update is pending |
inactive |
Domain has no nameservers delegated |
Reading Status Codes
A typical active domain might show:
Domain Status: clientTransferProhibited
Domain Status: clientDeleteProhibited
This means the registrar has locked the domain against transfers and deletions — standard security practice. The absence of ok is normal when other status codes are present; ok only appears when no other statuses are set.
A domain in trouble might show:
Domain Status: serverHold
Domain Status: clientTransferProhibited
serverHold means the registry has suspended DNS resolution — the domain won’t resolve. This happens for abuse (phishing, malware), legal orders, or UDRP decisions.
EPP Extensions
EPP’s “extensible” nature allows registries to add custom functionality beyond the base protocol. Common extensions include:
DNSSEC Extension (RFC 5910)
Allows registrars to manage DNSSEC delegation signer (DS) records:
<secDNS:create xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1">
<secDNS:dsData>
<secDNS:keyTag>12345</secDNS:keyTag>
<secDNS:alg>13</secDNS:alg>
<secDNS:digestType>2</secDNS:digestType>
<secDNS:digest>49FD46E6C4B45C55D4AC...</secDNS:digest>
</secDNS:dsData>
</secDNS:create>
Registry Grace Period Extension (RFC 3915)
Provides grace period status information so registrars can manage AGP deletions and redemption restorations.
Launch Phase Extension (RFC 8334)
Used during new gTLD launches to handle sunrise periods (trademark holders register first), landrush, and claims notifications.
Fee Extension
Various registries implement fee extensions to communicate dynamic or premium pricing for certain domain names. Before registering insurance.com, the registrar can query the fee extension to discover it costs $10,000/year instead of $10.
EPP in Practice
Connection Pools
Registrars managing millions of domains don’t open a new connection for each operation. They maintain connection pools — persistent EPP sessions to each registry, ready to process commands instantly. A large registrar might maintain dozens of concurrent connections to Verisign’s .com EPP servers.
Rate Limiting
Registries impose rate limits on EPP commands. Verisign, for example, limits the number of <check> commands per connection per second. This prevents abuse (like checking every possible 3-letter .com domain in rapid succession) while ensuring fair access for all registrars.
Testing Environments
Every registry operates an OT&E (Operational Test and Evaluation) environment — a sandbox where registrars test their EPP integration before going live. New registrars must successfully complete OT&E testing to become operational.
Key Takeaways
- EPP (RFC 5730-5734) is the XML protocol connecting registrars to registries for all domain operations
- Six core commands:
check,info,create,update,delete,renew, plustransferwith multiple operations - Status codes control what’s allowed —
client*codes are set by registrars,server*by registries clientTransferProhibitedis the standard “registrar lock” — enable it on every important domainserverHoldstops DNS resolution — a registry enforcement action- Extensions add DNSSEC, grace periods, launch phases, and premium pricing capabilities
- Persistent connections and connection pools make EPP performant at scale
This completes Part 3 — The Domain Ecosystem. You now understand how domain names are structured, how the registration industry operates, and the protocols and processes that make it all work. In Part 4, we’ll explore the security layer: DNSSEC, DNS-over-HTTPS, DNS hijacking, and the ongoing battle to keep the namespace trustworthy.