domaindetails.com
Knowledge Base/Technical Guides/Understanding EPP Protocol: How Domain Registration Really Works (2025)
Technical Guides

Understanding EPP Protocol: How Domain Registration Really Works (2025)

Complete guide to the Extensible Provisioning Protocol (EPP): XML-based domain registration, EPP commands, response codes, auth codes, how registrars communicate with registries, and troubleshooting domain issues.

15 min
Published 2025-12-01
Updated 2025-12-01
By DomainDetails Team

Quick Answer

EPP (Extensible Provisioning Protocol) is the standardized protocol that enables domain registrars to communicate with domain registries to register, transfer, renew, and manage domain names. Operating over TCP port 700 with TLS encryption, EPP uses XML-formatted commands and responses to handle all domain lifecycle operations. When you register a domain through GoDaddy, Namecheap, or any registrar, they're sending EPP commands like domain:create, domain:renew, or domain:transfer to the registry (Verisign for .com, PIR for .org, etc.). Understanding EPP helps you troubleshoot domain issues, comprehend EPP status codes, interpret transfer authorization codes, and grasp how the domain registration ecosystem functions behind the scenes.

Table of Contents

What is EPP?

EPP stands for Extensible Provisioning Protocol. It's the standardized protocol that registrars use to communicate with registries to manage domain names, IP addresses, and other internet resources.

The Simple Explanation

Think of domain registration like a retail system:

  • Registries (Verisign, PIR, Afilias) are the wholesalers who control top-level domains
  • Registrars (GoDaddy, Namecheap, Cloudflare) are the retailers who sell to customers
  • EPP is the ordering system that lets retailers place orders with wholesalers

When you register example.com at Namecheap:

  1. You fill out a form on Namecheap's website
  2. Namecheap's system creates an EPP domain:create command
  3. Namecheap sends this XML command to Verisign (the .com registry)
  4. Verisign processes the command and reserves the domain
  5. Verisign sends back an EPP response confirming registration
  6. Namecheap shows you a success message

All of this happens in seconds, entirely through EPP.

What EPP Manages

EPP handles the complete domain lifecycle:

Domain operations:

  • Create: Register a new domain
  • Check: Verify domain availability
  • Info: Query domain details
  • Update: Modify domain information (contacts, nameservers, status)
  • Renew: Extend domain registration period
  • Transfer: Move domain between registrars
  • Delete: Remove domain from registry

Other resources:

  • Contacts: Register and manage contact objects
  • Hosts: Register nameservers (host objects)
  • Authorization codes: Generate and verify transfer codes

Why EPP Matters to You

Even if you never interact with EPP directly, understanding it helps you:

  • Troubleshoot issues: EPP status codes explain why transfers fail or why domains are locked
  • Understand timing: EPP defines transfer timelines and renewal grace periods
  • Security awareness: EPP auth codes protect your domains from unauthorized transfers
  • Make informed decisions: Knowing EPP helps you choose registrars and interpret domain data

The History of EPP

Before EPP: The Wild West Era

1990s: Email-Based Registration

  • Registrars emailed plain-text domain requests to registries
  • Manual processing took hours or days
  • No standardization—each registry had different formats
  • High error rates due to manual data entry

Late 1990s: Proprietary Protocols

  • Large registrars developed custom integration systems
  • RRP (Registry Registrar Protocol) emerged as early standard
  • Still inconsistent across different registries
  • Security was minimal—passwords in plain text

EPP Development Timeline

1998: Development Begins The Internet Engineering Task Force (IETF) recognized the need for a standardized, secure protocol for domain provisioning. Work on EPP began under the PROVREG working group.

2000-2004: RFC Series Published The IETF published the original EPP specifications:

  • RFC 3730: EPP Protocol specification (base protocol)
  • RFC 3731: EPP Domain name mapping
  • RFC 3732: EPP Host mapping
  • RFC 3733: EPP Contact mapping

2004-2007: Industry Adoption

  • Verisign (.com, .net) transitioned to EPP
  • ICANN required EPP for all new gTLD registries
  • Most registrars upgraded systems to support EPP
  • Became the de facto standard for domain provisioning

2009: EPP 1.0 Standards Finalized Updated RFC series replaced the originals:

  • RFC 5730: EPP Protocol (superseded RFC 3730)
  • RFC 5731: Domain name mapping (superseded RFC 3731)
  • RFC 5732: Host mapping (superseded RFC 3732)
  • RFC 5733: Contact mapping (superseded RFC 3733)

2010s: Universal Adoption

  • All major registries implemented EPP
  • DNSSEC extensions added
  • IDN (Internationalized Domain Name) support
  • Registry-specific extensions proliferated

2020s: Modern EPP

  • Over 1,500 TLDs use EPP
  • Processing billions of domain transactions annually
  • Continuing evolution through extensions
  • Foundation for new RDAP protocol (Registration Data Access Protocol)

How EPP Works: The Architecture

The Three Layers

EPP operates in a client-server model with three main components:

1. EPP Client (Registrar Systems)

What it does:

  • Translates registrar's internal systems into EPP commands
  • Manages EPP sessions with multiple registries
  • Handles authentication and connection management
  • Processes EPP responses and updates registrar database

Example registrars: GoDaddy, Namecheap, Cloudflare Registrar, Google Domains

2. EPP Server (Registry Systems)

What it does:

  • Receives EPP commands from authorized registrars
  • Validates commands against registry policies
  • Executes operations on registry database
  • Returns standardized EPP responses
  • Enforces security and access controls

Example registries: Verisign (.com, .net), PIR (.org), Donuts (many new gTLDs)

3. Transport Layer

Connection details:

  • Protocol: TCP/IP
  • Port: 700 (standard) or 3121 (alternative)
  • Encryption: TLS 1.2 or higher (required)
  • Authentication: Username/password or certificate-based
  • Session-based: Persistent connection for multiple commands

How a Domain Registration Flows Through EPP

Let's trace the complete flow when you register example.com:

Step 1: Customer Action

You → Namecheap Website → Search for "example.com" → Add to cart → Checkout

Step 2: Registrar Prepares Namecheap's system:

  • Establishes EPP session with Verisign (.com registry)
  • Authenticates using TLS certificate and credentials
  • Sends EPP greeting received from server

Step 3: Domain Availability Check

Namecheap sends → domain:check command
Verisign responds → domain available

Step 4: Domain Creation

Namecheap sends → domain:create command with:
  - Domain name: example.com
  - Registration period: 1 year
  - Contact IDs: registrant, admin, tech
  - Nameservers: ns1.namecheap.com, ns2.namecheap.com
  - Auth code: Randomly generated

Verisign processes → Creates domain in registry
Verisign responds → Success, creation date, expiration date

Step 5: Registrar Confirmation

Namecheap updates internal database → Sends confirmation email to you

Total time: Typically 1-3 seconds for the EPP commands

EPP Session Management

EPP uses persistent sessions rather than stateless requests:

Session Lifecycle:

  1. Connect: Client establishes TLS connection to registry
  2. Greeting: Server sends greeting with capabilities
  3. Login: Client authenticates with credentials
  4. Commands: Client sends multiple commands in the session
  5. Logout: Client terminates session gracefully
  6. Disconnect: TCP connection closes

Why sessions?

  • Performance: Avoid reconnection overhead
  • Security: Maintain authenticated state
  • Transactions: Group related operations
  • Rate limiting: Control per-session limits

EPP Command Flow Diagram

┌─────────────┐                    ┌──────────────┐
│  Registrar  │                    │   Registry   │
│   (Client)  │                    │   (Server)   │
└──────┬──────┘                    └──────┬───────┘
       │                                  │
       │  1. TCP Connect (port 700)      │
       ├─────────────────────────────────>│
       │                                  │
       │  2. Server Greeting              │
       │<─────────────────────────────────┤
       │                                  │
       │  3. <login> Command              │
       ├─────────────────────────────────>│
       │                                  │
       │  4. Login Success Response       │
       │<─────────────────────────────────┤
       │                                  │
       │  5. <domain:check> Command       │
       ├─────────────────────────────────>│
       │                                  │
       │  6. Check Response (available)   │
       │<─────────────────────────────────┤
       │                                  │
       │  7. <domain:create> Command      │
       ├─────────────────────────────────>│
       │                                  │
       │  8. Create Success Response      │
       │<─────────────────────────────────┤
       │                                  │
       │  9. <logout> Command             │
       ├─────────────────────────────────>│
       │                                  │
       │  10. Logout Success Response     │
       │<─────────────────────────────────┤
       │                                  │
       │  11. TCP Disconnect              │
       └──────────────────────────────────┘

EPP Commands Overview

EPP defines three categories of commands:

Query Commands (Read-Only)

These commands retrieve information without modifying registry data:

Command Purpose Example Use Case
check Verify if object is available Check if domain is registered
info Retrieve object details Get domain expiration date
poll Retrieve pending messages Check for transfer notifications
transfer (query) Check transfer status Monitor pending transfer

Transform Commands (Write Operations)

These commands modify registry data:

Command Purpose Example Use Case
create Register new object Register a domain
delete Remove object Delete domain after expiration
renew Extend registration period Renew domain for another year
update Modify object details Change nameservers
transfer (request) Initiate transfer Move domain to new registrar
transfer (approve) Approve pending transfer Losing registrar approves transfer
transfer (reject) Reject pending transfer Losing registrar denies transfer
transfer (cancel) Cancel pending transfer Gaining registrar cancels transfer

Session Commands

These commands manage the EPP session itself:

Command Purpose Example Use Case
hello Retrieve server greeting Test connection
login Authenticate session Start authenticated session
logout Terminate session End session gracefully

EPP Command Details

Domain Check

Purpose: Verify if one or more domain names are available for registration.

When it's used:

  • Domain search on registrar website
  • Bulk availability checking
  • Pre-registration validation

Example request:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <check>
      <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:name>example.org</domain:name>
      </domain:check>
    </check>
    <clTRID>ABC-12345</clTRID>
  </command>
</epp>

Example response:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <resData>
      <domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:cd>
          <domain:name avail="1">example.com</domain:name>
        </domain:cd>
        <domain:cd>
          <domain:name avail="0">example.net</domain:name>
          <domain:reason>In use</domain:reason>
        </domain:cd>
        <domain:cd>
          <domain:name avail="1">example.org</domain:name>
        </domain:cd>
      </domain:chkData>
    </resData>
    <trID>
      <clTRID>ABC-12345</clTRID>
      <svTRID>XYZ-67890</svTRID>
    </trID>
  </response>
</epp>

Key fields:

  • avail="1": Domain is available
  • avail="0": Domain is registered
  • domain:reason: Why domain is unavailable (optional)

Domain Create

Purpose: Register a new domain name.

When it's used:

  • Customer completes domain purchase
  • Bulk registration operations
  • Drop-catch registration (expired domains)

Example request:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <create>
      <domain:create xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.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-001</domain:registrant>
        <domain:contact type="admin">CONTACT-002</domain:contact>
        <domain:contact type="tech">CONTACT-003</domain:contact>
        <domain:authInfo>
          <domain:pw>2fooBAR</domain:pw>
        </domain:authInfo>
      </domain:create>
    </create>
    <clTRID>ABC-12346</clTRID>
  </command>
</epp>

Example response:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <resData>
      <domain:creData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.com</domain:name>
        <domain:crDate>2025-12-01T12:00:00.0Z</domain:crDate>
        <domain:exDate>2027-12-01T12:00:00.0Z</domain:exDate>
      </domain:creData>
    </resData>
    <trID>
      <clTRID>ABC-12346</clTRID>
      <svTRID>XYZ-67891</svTRID>
    </trID>
  </response>
</epp>

Required fields:

  • domain:name: Domain to register
  • domain:period: Registration length (years or months)
  • domain:registrant: Registrant contact ID
  • domain:authInfo: Authorization password for future transfers

Optional fields:

  • domain:ns: Nameservers (can be added later)
  • domain:contact: Admin and technical contacts

Domain Info

Purpose: Retrieve detailed information about a domain.

When it's used:

  • Displaying domain details in registrar control panel
  • Verifying domain configuration
  • Auditing domain status

Example request:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <info>
      <domain:info xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.com</domain:name>
        <domain:authInfo>
          <domain:pw>2fooBAR</domain:pw>
        </domain:authInfo>
      </domain:info>
    </info>
    <clTRID>ABC-12347</clTRID>
  </command>
</epp>

Example response (abbreviated for readability):

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <resData>
      <domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.com</domain:name>
        <domain:roid>EXAMPLE1-REP</domain:roid>
        <domain:status s="ok"/>
        <domain:registrant>CONTACT-001</domain:registrant>
        <domain:contact type="admin">CONTACT-002</domain:contact>
        <domain:contact type="tech">CONTACT-003</domain:contact>
        <domain:ns>
          <domain:hostObj>ns1.example.com</domain:hostObj>
          <domain:hostObj>ns2.example.com</domain:hostObj>
        </domain:ns>
        <domain:clID>Registrar123</domain:clID>
        <domain:crID>Registrar123</domain:crID>
        <domain:crDate>2020-01-15T00:00:00.0Z</domain:crDate>
        <domain:exDate>2026-01-15T00:00:00.0Z</domain:exDate>
        <domain:authInfo>
          <domain:pw>2fooBAR</domain:pw>
        </domain:authInfo>
      </domain:infData>
    </resData>
    <trID>
      <clTRID>ABC-12347</clTRID>
      <svTRID>XYZ-67892</svTRID>
    </trID>
  </response>
</epp>

Key information returned:

  • Domain status codes
  • Registration and expiration dates
  • Nameservers
  • Contact IDs
  • Sponsoring registrar (clID)
  • Auth code (if authorized)

Domain Update

Purpose: Modify domain information such as nameservers, contacts, or status codes.

When it's used:

  • Changing nameservers
  • Updating contact information
  • Adding/removing status codes (locks)
  • Changing auth code

Example request (changing nameservers):

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <update>
      <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:add>
        <domain:rem>
          <domain:ns>
            <domain:hostObj>ns1.example.com</domain:hostObj>
          </domain:ns>
        </domain:rem>
        <domain:chg>
          <domain:authInfo>
            <domain:pw>newAuthCode123</domain:pw>
          </domain:authInfo>
        </domain:chg>
      </domain:update>
    </update>
    <clTRID>ABC-12348</clTRID>
  </command>
</epp>

Update structure:

  • domain:add: Add elements (nameservers, contacts, status codes)
  • domain:rem: Remove elements
  • domain:chg: Change elements (auth code, registrant)

Domain Renew

Purpose: Extend a domain's registration period.

When it's used:

  • Manual domain renewal
  • Auto-renewal processing
  • Bulk renewal operations

Example request:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <renew>
      <domain:renew xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.com</domain:name>
        <domain:curExpDate>2026-01-15</domain:curExpDate>
        <domain:period unit="y">1</domain:period>
      </domain:renew>
    </renew>
    <clTRID>ABC-12349</clTRID>
  </command>
</epp>

Example response:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <resData>
      <domain:renData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.com</domain:name>
        <domain:exDate>2027-01-15T00:00:00.0Z</domain:exDate>
      </domain:renData>
    </resData>
    <trID>
      <clTRID>ABC-12349</clTRID>
      <svTRID>XYZ-67894</svTRID>
    </trID>
  </response>
</epp>

Required fields:

  • domain:name: Domain to renew
  • domain:curExpDate: Current expiration date (validation)
  • domain:period: Renewal length (typically 1-10 years)

Important: The curExpDate must match the registry's current expiration date, preventing accidental double renewals.


Domain Transfer

Purpose: Move domain sponsorship from one registrar to another.

Transfer types:

  • request: Gaining registrar initiates transfer
  • query: Check transfer status
  • approve: Losing registrar approves transfer
  • reject: Losing registrar denies transfer
  • cancel: Gaining registrar cancels transfer

Example transfer request:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <transfer op="request">
      <domain:transfer xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.com</domain:name>
        <domain:period unit="y">1</domain:period>
        <domain:authInfo>
          <domain:pw>2fooBAR</domain:pw>
        </domain:authInfo>
      </domain:transfer>
    </transfer>
    <clTRID>ABC-12350</clTRID>
  </command>
</epp>

Example response:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <response>
    <result code="1001">
      <msg>Command completed successfully; action pending</msg>
    </result>
    <resData>
      <domain:trnData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.com</domain:name>
        <domain:trStatus>pending</domain:trStatus>
        <domain:reID>LoseRegistrar</domain:reID>
        <domain:reDate>2025-12-01T12:00:00.0Z</domain:reDate>
        <domain:acID>GainRegistrar</domain:acID>
        <domain:acDate>2025-12-06T12:00:00.0Z</domain:acDate>
      </domain:trnData>
    </resData>
    <trID>
      <clTRID>ABC-12350</clTRID>
      <svTRID>XYZ-67895</svTRID>
    </trID>
  </response>
</epp>

Transfer process:

  1. Gaining registrar sends transfer request with auth code
  2. Registry validates auth code
  3. Transfer enters pending state (typically 5-7 days)
  4. Losing registrar can approve (completes immediately) or reject
  5. If no action, transfer auto-approves after waiting period
  6. Registry updates sponsoring registrar

Domain Delete

Purpose: Remove a domain from the registry (rare operation).

When it's used:

  • Deleting domains during grace period (refund)
  • Registry administrator operations
  • Scheduled deletion after expiration

Example request:

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <delete>
      <domain:delete xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>example.com</domain:name>
      </domain:delete>
    </delete>
    <clTRID>ABC-12351</clTRID>
  </command>
</epp>

Important notes:

  • Rarely used by registrars (domains normally expire, not delete)
  • Add Grace Period (5 days) allows deletion with full refund
  • After grace period, domains expire and enter redemption period
  • Only registry operators can delete after expiration

EPP Response Structure

All EPP responses follow a consistent XML structure:

Success Response

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <msgQ count="5" id="12345">
      <qDate>2025-12-01T12:00:00.0Z</qDate>
      <msg>Transfer requested.</msg>
    </msgQ>
    <resData>
      <!-- Command-specific response data -->
    </resData>
    <trID>
      <clTRID>ABC-12345</clTRID>
      <svTRID>XYZ-67890</svTRID>
    </trID>
  </response>
</epp>

Key elements:

  • result code: Numeric status code (1000 = success)
  • msg: Human-readable message
  • msgQ: Message queue info (pending notifications)
  • resData: Command-specific response data
  • trID: Transaction IDs (client and server)

Error Response

<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <response>
    <result code="2201">
      <msg>Authorization error</msg>
      <extValue>
        <value>
          <domain:name>example.com</domain:name>
        </value>
        <reason>Invalid authorization information</reason>
      </extValue>
    </result>
    <trID>
      <clTRID>ABC-12345</clTRID>
      <svTRID>XYZ-67890</svTRID>
    </trID>
  </response>
</epp>

Error details:

  • result code: Error code (2xxx = command failed)
  • msg: Error description
  • extValue: Additional error context (optional)
  • reason: Specific reason for failure

EPP Status Codes

EPP responses use numeric status codes similar to HTTP:

Success Codes (1xxx)

Code Meaning Description
1000 Success Command completed successfully
1001 Success (pending) Command completed; action pending
1300 Success (no messages) Command completed; no queue messages
1301 Success (ack to dequeue) Command completed; ack message to dequeue
1500 Success (ending session) Command completed successfully; ending session

Client Error Codes (2xxx)

Code Meaning Common Cause
2000 Unknown command Invalid EPP command
2001 Command syntax error Malformed XML
2002 Command use error Using command incorrectly
2003 Required parameter missing Missing mandatory field
2004 Parameter value range error Value out of allowed range
2005 Parameter value syntax error Invalid format
2100 Unimplemented protocol version EPP version not supported
2101 Unimplemented command Command not supported by registry
2102 Unimplemented option Option not supported
2103 Unimplemented extension Extension not supported
2104 Billing failure Payment or credit issue
2105 Object not eligible for renewal Domain can't be renewed (e.g., too early)
2106 Object not eligible for transfer Domain can't be transferred
2200 Authentication error Login failed
2201 Authorization error Insufficient privileges or invalid auth code
2202 Invalid authorization information Wrong auth code
2300 Object pending transfer Domain has pending transfer
2301 Object not pending transfer No pending transfer exists
2302 Object exists Domain already registered
2303 Object does not exist Domain not found
2304 Object status prohibits operation Domain locked or in wrong state
2305 Object association prohibits operation Dependencies prevent operation
2306 Parameter value policy error Value violates policy
2307 Unimplemented object service Service not available
2308 Data management policy violation Operation violates data policy

Server Error Codes (5xxx)

Code Meaning Description
2400 Command failed Generic failure
2500 Command failed; server closing connection Fatal error
2501 Authentication error; server closing Auth failed
2502 Session limit exceeded; server closing Too many sessions

EPP Authorization Codes (Auth Codes)

Authorization codes (also called EPP codes, auth codes, or transfer keys) are passwords that protect domains from unauthorized transfers.

What are Auth Codes?

Auth codes are randomly generated passwords assigned to each domain. To transfer a domain to a new registrar, you must provide the correct auth code to prove ownership.

Example auth code: Xy7$kL2p!9Qm

Auth Code Format

Typical characteristics:

  • Length: 8-32 characters
  • Complexity: Mix of letters, numbers, symbols
  • Case-sensitive: Yes
  • Validity: Permanent until changed

Generated by: Registry when domain is created, or by current registrar on request

How Auth Codes Work

Domain transfer process:

  1. Domain owner requests auth code from current registrar
  2. Registrar retrieves auth code from registry via EPP domain:info
  3. Owner provides auth code to new registrar
  4. New registrar submits transfer via EPP domain:transfer with auth code
  5. Registry validates auth code
  6. If valid, transfer proceeds; if invalid, transfer rejected (code 2202)

Getting Your Auth Code

From your registrar:

  • Log into registrar control panel
  • Find domain management section
  • Look for "Transfer Out", "Auth Code", or "EPP Code"
  • Click to reveal or email auth code

Registrar requirements:

  • ICANN requires registrars to provide auth codes within 5 days
  • Most registrars provide immediately
  • Some require account verification first

Changing Auth Codes

Registrars can change auth codes via EPP domain:update:

<domain:chg>
  <domain:authInfo>
    <domain:pw>newAuthCode456</domain:pw>
  </domain:authInfo>
</domain:chg>

When to change auth code:

  • After failed transfer attempt (security)
  • If auth code was compromised
  • Regular security rotation

Auth Code Security

Protecting your auth code:

  • ✅ Store securely (password manager)
  • ✅ Only share with trusted registrars
  • ✅ Change after any transfer
  • ✅ Enable transfer lock to prevent unauthorized use
  • ❌ Don't email in plain text
  • ❌ Don't post publicly

Transfer locks override auth codes: Even with a valid auth code, domains with clientTransferProhibited or serverTransferProhibited status cannot be transferred until unlocked.

XML Structure of EPP Messages

EPP uses XML for all communication. Understanding the structure helps troubleshoot issues.

Basic XML Structure

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <!-- Commands or responses go here -->
</epp>

XML Namespaces

EPP uses XML namespaces to organize elements:

Core namespace:

xmlns="urn:ietf:params:xml:ns:epp-1.0"

Domain namespace:

xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"

Contact namespace:

xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"

Host namespace:

xmlns:host="urn:ietf:params:xml:ns:host-1.0"

Complete Command Example

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
  <command>
    <check>
      <domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"
                    xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
        <domain:name>example.com</domain:name>
      </domain:check>
    </check>
    <clTRID>ABC-12345</clTRID>
  </command>
</epp>

XML Schema Validation

EPP servers validate all commands against XML schemas:

EPP base schema: epp-1.0.xsd Domain schema: domain-1.0.xsd Contact schema: contact-1.0.xsd Host schema: host-1.0.xsd

Invalid XML results in:

  • Code 2001: Command syntax error
  • Server rejects command without processing

EPP Extensions

EPP's extensibility allows registries to add custom functionality beyond the core protocol.

Why Extensions Exist

Core EPP covers basics, but registries need specialized features:

  • DNSSEC key management
  • IDN (internationalized domain names)
  • Registry-specific policies
  • Premium pricing
  • Custom fields

Common EPP Extensions

1. DNSSEC Extension (secDNS)

Purpose: Manage DNSSEC key material

Namespace: urn:ietf:params:xml:ns:secDNS-1.1

Example (adding DNSSEC):

<extension>
  <secDNS:create xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1">
    <secDNS:dsData>
      <secDNS:keyTag>12345</secDNS:keyTag>
      <secDNS:alg>8</secDNS:alg>
      <secDNS:digestType>2</secDNS:digestType>
      <secDNS:digest>38EC...</secDNS:digest>
    </secDNS:dsData>
  </secDNS:create>
</extension>

2. Launch Extension

Purpose: Handle new TLD launches (sunrise, landrush phases)

Namespace: urn:ietf:params:xml:ns:launch-1.0

Example (sunrise registration):

<extension>
  <launch:create xmlns:launch="urn:ietf:params:xml:ns:launch-1.0">
    <launch:phase>sunrise</launch:phase>
    <launch:smd>PD94bWwgd...</launch:smd>
  </launch:create>
</extension>

3. Registry Grace Period (RGP)

Purpose: Manage grace period operations

Namespace: urn:ietf:params:xml:ns:rgp-1.0

Example (restore after redemption):

<extension>
  <rgp:update xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0">
    <rgp:restore op="request"/>
  </rgp:update>
</extension>

4. IDN Extension

Purpose: Handle internationalized domain names

Namespace: Varies by registry

Example (language tag):

<extension>
  <idn:create xmlns:idn="urn:ietf:params:xml:ns:idn-1.0">
    <idn:languageTag>zh-Hans</idn:languageTag>
  </idn:create>
</extension>

5. Premium Domain Pricing

Purpose: Handle premium domain pricing

Namespace: Registry-specific

Example (fee extension):

<extension>
  <fee:check xmlns:fee="urn:ietf:params:xml:ns:fee-0.6">
    <fee:domain>
      <fee:name>premium.com</fee:name>
      <fee:command>create</fee:command>
      <fee:period unit="y">1</fee:period>
    </fee:domain>
  </fee:check>
</extension>

Registry-Specific Extensions

Each registry can define proprietary extensions:

Verisign (.com, .net):

  • Sync extension
  • IDN language extension
  • NameStore extension (product bundling)

PIR (.org):

  • ID protection extension
  • Registry lock extension

Nominet (.uk):

  • Direct Rights Protection extension
  • Tag extension

EPP and Domain Transfers

Domain transfers are one of EPP's most complex operations. Understanding the process helps troubleshoot transfer issues.

Transfer Prerequisites

Before transfer can start:

  1. ✅ Domain unlocked (no clientTransferProhibited status)
  2. ✅ Valid auth code obtained
  3. ✅ Domain registered at least 60 days
  4. ✅ No pending transfer
  5. ✅ Not within 60 days of previous transfer
  6. ✅ Not expired

Transfer Timeline

Day 0: Gaining registrar submits EPP transfer request

  • Registry validates auth code
  • Transfer enters pending status
  • Losing registrar notified via EPP poll message

Day 0-5: Waiting period

  • Losing registrar can approve (instant transfer)
  • Losing registrar can reject (transfer fails)
  • Domain owner can cancel at gaining registrar

Day 5: Auto-approval

  • If losing registrar takes no action, transfer auto-approves
  • Registry updates sponsoring registrar
  • Domain renewed for 1 year (added to current expiration)

Day 5+: Transfer complete

  • Gaining registrar now controls domain
  • Auth code should be changed

EPP Transfer States

State Meaning Next Action
clientApproved Losing registrar approved Transfer completes immediately
clientRejected Losing registrar rejected Transfer fails; retry after fixing issues
clientCancelled Gaining registrar cancelled Transfer cancelled
pending Awaiting action Auto-approves after 5 days
serverApproved Registry approved Rare; registry intervention
serverCancelled Registry cancelled Rare; registry intervention

Common Transfer Failures

Code 2201: Authorization error

  • Invalid or incorrect auth code
  • Auth code expired
  • Fix: Get correct auth code from current registrar

Code 2304: Object status prohibits operation

  • Domain locked (clientTransferProhibited)
  • Fix: Unlock domain at current registrar

Code 2106: Object not eligible for transfer

  • Domain registered less than 60 days ago
  • Transfer within 60 days of previous transfer
  • Fix: Wait until eligible

Code 2302: Object exists (transfer already pending)

  • Another transfer is in progress
  • Fix: Cancel existing transfer or wait for completion

Transfer EPP Flow

Gaining Registrar                Registry               Losing Registrar
       |                            |                            |
       | 1. transfer request        |                            |
       |   (with auth code)         |                            |
       |--------------------------->|                            |
       |                            |                            |
       |                            | 2. Validate auth code      |
       |                            | 3. Check eligibility       |
       |                            | 4. Set status: pending     |
       |                            |                            |
       |                            | 5. Poll message:           |
       |                            |    transfer requested      |
       |                            |--------------------------->|
       |                            |                            |
       | 6. Response: pending       |                            |
       |<---------------------------|                            |
       |                            |                            |
       |                            |     [ 5-day wait period ]  |
       |                            |                            |
       |                            | 7. Auto-approve (or manual)|
       |                            | 8. Update sponsorship      |
       |                            | 9. Renew domain +1 year    |
       |                            |                            |
       | 10. Poll message:          |                            |
       |     transfer completed     |                            |
       |<---------------------------|                            |
       |                            |                            |
       |                            | 11. Poll message:          |
       |                            |     transfer completed     |
       |                            |--------------------------->|

EPP Security Features

EPP was designed with security as a core requirement:

Transport Layer Security (TLS)

Required encryption:

  • All EPP communication uses TLS 1.2 or higher
  • Registry servers reject unencrypted connections
  • Prevents eavesdropping and man-in-the-middle attacks

Certificate validation:

  • Registrars verify registry's SSL certificate
  • Some registries require client certificates (mutual TLS)

Authentication

Credentials:

  • Username and password required for login
  • Some registries use client certificates instead
  • Session authentication persists until logout

Login command:

<login>
  <clID>RegistrarID</clID>
  <pw>EncryptedPassword</pw>
  <newPW>NewPasswordOptional</newPW>
  <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>
    <objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
  </svcs>
</login>

Authorization

Object-level authorization:

  • Registrars can only modify domains they sponsor
  • Auth codes required for cross-registrar operations
  • Contact/host objects have ownership rules

Status-based protection:

  • Status codes like clientTransferProhibited prevent unauthorized transfers
  • clientUpdateProhibited prevents unauthorized changes
  • clientDeleteProhibited prevents accidental deletion

Rate Limiting

Registry-imposed limits:

  • Maximum commands per second (e.g., 10/second)
  • Maximum concurrent sessions (e.g., 5 per registrar)
  • Throttling during high load

Protects against:

  • Abuse and resource exhaustion
  • Accidental loops in registrar software
  • Competitive domain sniping

Audit Trail

Transaction IDs:

  • Every command has unique client transaction ID (clTRID)
  • Every response has unique server transaction ID (svTRID)
  • Registries log all transactions for compliance

Logging requirements:

  • ICANN requires transaction logs retained for years
  • Used for dispute resolution
  • Compliance auditing

How EPP Helps Troubleshoot Domain Issues

Understanding EPP empowers you to diagnose and fix domain problems:

Issue: Domain Won't Transfer

Check EPP status codes:

clientTransferProhibited → Unlock at current registrar
serverTransferProhibited → Contact registry (rare)
pendingTransfer → Wait for current transfer to complete

Verify eligibility:

  • Registered less than 60 days? Wait.
  • Transferred within 60 days? Wait.
  • Expired? Renew first.

Test auth code:

  • Try transfer at new registrar—EPP will return code 2201 if auth code is invalid

Issue: Nameservers Won't Update

Check EPP status codes:

clientUpdateProhibited → Unlock at registrar
serverUpdateProhibited → Contact registry
serverHold → Domain suspended (often for non-payment)

Verify nameserver format:

  • EPP requires fully qualified domain names: ns1.example.com (not ns1)
  • Must have valid A/AAAA records

Check for EPP errors:

  • Registrar control panel may show EPP error codes
  • Code 2005 = Invalid nameserver format
  • Code 2303 = Nameserver doesn't exist in registry

Issue: Domain Appears "Locked"

Identify specific lock:

clientUpdateProhibited → Prevents updates (nameservers, contacts)
clientDeleteProhibited → Prevents deletion
clientTransferProhibited → Prevents transfers
clientHold → Domain doesn't resolve (DNS disabled)

Resolution:

  • Registrar-applied locks (client*) → Unlock in registrar control panel
  • Registry-applied locks (server*) → Contact registrar to contact registry
  • redemptionPeriod → Domain expired; restore via registrar

Issue: Contact Information Not Updating

Possible EPP causes:

  • Code 2304: Domain locked with clientUpdateProhibited
  • Code 2306: Contact info violates registry policy (e.g., invalid country code)
  • Code 2002: Using wrong contact ID format

Troubleshooting:

  • Verify domain is unlocked
  • Check that required fields are provided
  • Ensure format matches registry requirements

Issue: Transfer Failed with "Authorization Error"

EPP Code 2201 indicates:

  • Wrong auth code entered
  • Auth code expired (some registries time-limit codes)
  • Auth code not yet generated

Fix:

  1. Log into current registrar
  2. Request/reveal auth code (may take up to 5 days per ICANN)
  3. Copy carefully (auth codes are case-sensitive)
  4. Paste into new registrar's transfer form
  5. Retry transfer

Reading Registrar Error Messages

Many registrars expose EPP codes in error messages:

Good registrar error message:

Transfer failed: Authorization error (EPP code 2201).
Please verify your authorization code and try again.

Poor registrar error message:

Transfer failed. Please contact support.

If no code shown: Ask support for the EPP error code—helps diagnose issue faster.

EPP vs Other Protocols

How does EPP compare to other domain-related protocols?

EPP vs WHOIS

Feature EPP WHOIS
Purpose Domain provisioning Domain information lookup
Users Registrars only Anyone
Authentication Required None
Transport TCP port 700, TLS TCP port 43, plain text
Format XML Unstructured text
Operations Create, update, delete, transfer Read-only queries

Relationship: EPP manages domains; WHOIS displays domain info publicly.

EPP vs RDAP

Feature EPP RDAP
Purpose Domain provisioning Domain information lookup
Users Registrars only Anyone
Authentication Required Optional (for extended access)
Transport TCP port 700, TLS HTTPS (RESTful API)
Format XML JSON
Operations Full CRUD Read-only

Relationship: EPP is the "write" protocol (registrars modify); RDAP is the "read" protocol (public queries).

EPP vs DNS

Feature EPP DNS
Purpose Domain registration management Domain name resolution
Users Registrars Everyone
Transport TCP port 700, TLS UDP port 53 (TCP for large)
Format XML Binary
Operations Register/update domains Resolve names to IPs

Relationship: EPP manages domain records at registry; DNS resolves domains at runtime.

EPP vs RRP (Legacy)

Feature EPP RRP
Status Current standard Deprecated
Format XML Line-based text
Transport TCP+TLS TCP, plain text
Extensibility XML extensions Limited
Security TLS encryption, auth Minimal

History: RRP was EPP's predecessor. EPP replaced RRP due to superior security, extensibility, and standardization.

Frequently Asked Questions

Can I use EPP as an individual domain owner?

No, EPP access is restricted to accredited registrars. As an individual, you interact with your registrar's interface, which then uses EPP on your behalf to communicate with registries. There is no public EPP access.

Why do domain transfers take 5-7 days?

The 5-day window is built into the EPP transfer process to give the losing registrar time to verify the transfer with the domain owner and prevent fraud. Losing registrars can approve immediately (instant transfer), but if they take no action, the transfer auto-approves after 5 days. This delay protects against unauthorized transfers.

What is the difference between an EPP code and an auth code?

They're the same thing. "Auth code," "EPP code," "transfer key," and "authorization code" all refer to the password required to transfer a domain. The technically correct term per EPP specifications is "authorization information" (authInfo), but "auth code" is most common.

Can registrars see EPP auth codes for domains they don't manage?

No. EPP enforces strict authorization. A registrar can only retrieve auth codes (via domain:info) for domains they currently sponsor. This prevents registrars from initiating unauthorized transfers of competitors' domains.

Why do some domains have status codes like clientTransferProhibited?

These EPP status codes provide security by locking domains against specific operations. clientTransferProhibited prevents transfers, protecting against domain hijacking. clientUpdateProhibited prevents unauthorized nameserver changes. Registrars apply these locks either automatically (as a security feature) or at the domain owner's request.

What happens if my registrar sends an invalid EPP command?

The registry's EPP server validates all commands against XML schemas. If a command is malformed, the registry returns an error code (typically 2001 for syntax errors or 2003 for missing required fields) without processing the command. The registrar's system should handle the error and either retry with a corrected command or alert the user.

Can I get EPP logs for my domains?

Generally no, but you can ask your registrar. EPP transaction logs are maintained by registrars and registries for compliance purposes, not typically shared with domain owners. However, some registrars may provide limited EPP history (like "domain updated on [date]") in control panels.

How does EPP handle domain privacy/WHOIS privacy?

EPP doesn't directly handle WHOIS privacy. When a registrar enables privacy, they typically: (1) Update the domain's contact objects via EPP to point to proxy contacts, or (2) Use a registrar-provided privacy service that intercepts WHOIS queries. The domain's EPP contact objects may show the privacy service's contact IDs instead of the owner's.

What is the EPP poll queue?

The poll queue is a message system where registries send notifications to registrars about important events. Registrars retrieve messages using the EPP poll command. Common messages include: transfer requests, transfer completions, expiration warnings, and registry policy updates. Each message has a unique ID and must be acknowledged to remove it from the queue.

Can domains be registered through EPP without a registrar?

No. EPP access requires accreditation. To become an accredited registrar, organizations must meet ICANN's requirements (financial stability, technical infrastructure, compliance capabilities) and pay accreditation fees ($3,500 application + $4,000/year). Individuals and small businesses use existing registrars instead.

Key Takeaways

  • EPP is the backbone of domain registration, enabling registrars to communicate with registries for all domain operations

  • XML-based protocol operating over TLS-encrypted TCP port 700, providing security and standardization

  • Core commands include create, check, info, update, renew, transfer, and delete—covering the complete domain lifecycle

  • EPP status codes (like clientTransferProhibited) control what operations are allowed and help troubleshoot issues

  • Auth codes are EPP's security mechanism, required for domain transfers to prevent unauthorized moves

  • EPP responses use numeric codes similar to HTTP—1xxx = success, 2xxx = client error, 5xxx = server error

  • Extensions enable customization for DNSSEC, IDN, premium pricing, and registry-specific features

  • Transfer process takes 5-7 days with built-in protections against fraud through auth code verification

  • Registrars-only access means individuals interact with registrar interfaces, which use EPP behind the scenes

  • Understanding EPP helps troubleshoot domain transfer failures, update issues, and lock-related problems

Next Steps

If You're a Domain Owner:

  1. Learn EPP status codes to understand why domains are locked or transfers fail
  2. Secure your auth codes like passwords—they protect your domains from unauthorized transfers
  3. Check domain status in your registrar control panel—look for EPP status codes
  4. Understand transfer process before initiating—know the 5-day timeline and requirements

If You're a Developer:

  1. Become an accredited registrar if you're building a domain registration business (ICANN application process)
  2. Study EPP RFCs: RFC 5730 (base), RFC 5731 (domain mapping), RFC 5732 (host), RFC 5733 (contact)
  3. Use EPP client libraries: Many languages have EPP libraries (PHP-EPP, EPPy for Python, etc.)
  4. Test in OT&E environment: Registries provide test environments for EPP integration

If You're Experiencing Domain Issues:

  1. Ask for EPP error codes when contacting registrar support—helps diagnose faster
  2. Check EPP status codes via WHOIS or RDAP to identify specific locks
  3. Understand transfer eligibility before attempting—60-day restrictions, unlock requirements
  4. Verify auth code carefully if transfers fail—auth codes are case-sensitive

Research Sources

This article was researched using information from authoritative sources: