xmlrpc.php is the file in the root of every WordPress site that answers XML-RPC, the remote API WordPress used before the REST API existed. It lets an app log in, publish posts and send pingbacks over HTTP. Very few sites still need it, while bots use it every day to guess passwords and to send pingback requests to other sites. This guide explains what the file does, how it is attacked, how to check whether anything on your site still depends on it, and how to disable XML-RPC in WordPress at the level that fits your setup. It is part of the WordPress security checklist, where XML-RPC is step 6.
Quick answer
- You can't delete
xmlrpc.php. It is a core file and the next update puts it back. Block it or switch it off instead. - Check what uses it first: Jetpack's connection, some mobile and desktop publishing apps, and a few remote-management and publishing services.
- Nothing uses it? Block the file at the server or CDN so requests never reach PHP. That stops both login guessing and pingbacks.
- Something uses it? Keep it open and rate-limit
POST /xmlrpc.phpat your CDN or server instead. - The
xmlrpc_enabledfilter is a half measure. It switches off methods that need a login, but pingbacks still work. - Verify with
curl: a blocked file answers 403 (or 404) to a POST.
What is xmlrpc.php?
XML-RPC is a protocol from the late 1990s: a client sends an XML document over HTTP naming a method and its arguments, and the server sends back an XML answer. WordPress implemented it so that desktop editors, the first mobile apps and other blogs could talk to a site. Methods such as wp.newPost, wp.getUsersBlogs and pingback.ping all go through one address, https://example.com/xmlrpc.php.
WordPress still ships and enables it for backwards compatibility. The REST API, under /wp-json/, has replaced it for the block editor and for almost every modern plugin and app. Since WordPress 5.6, application passwords (Users → Profile → Application Passwords) let apps authenticate to the REST API without your main password.
Your site advertises the endpoint in two places: a <link rel="EditURI"> tag in the page head pointing to xmlrpc.php?rsd, and an X-Pingback header on single posts that accept pings. That is how bots find it, although most simply try the address on every site they see.
How attackers use xmlrpc.php
Password guessing
wp.getUsersBlogs and other authenticated methods take a username and password in the request body. That gives brute-force scripts a second login form, one without the cookies, redirects and nonces of wp-login.php, so it is simpler to automate. Login-limiting features that only watch wp-login.php miss these attempts.
XML-RPC also has system.multicall, which runs many methods in one request. Until WordPress 4.4 a script could pack hundreds of password guesses into a single HTTP request. Since 4.4, all further login attempts inside a multicall fail after the first failed one, so the amplification no longer works. Plain one-guess-per-request attacks still do, and they are cheap.
Pingback abuse
pingback.ping asks your site to fetch another URL to verify a link. Attackers send thousands of these requests to thousands of WordPress sites, all naming the same victim, and the sites dutifully fetch the victim's page: a distributed denial-of-service attack with your server as one of the senders. The same method can be used to make your server request internal addresses or to reveal its real IP behind a CDN. It needs no login, which is why the xmlrpc_enabled filter does not stop it.
Load
Even failed requests start PHP and load WordPress. On shared hosting, a steady stream of POST /xmlrpc.php can use enough CPU to slow the whole site. If your access log shows hundreds of these a day and you do not use XML-RPC, that is capacity spent on bots.
Does anything on your site still need XML-RPC?
Check before you block it. Things that commonly use it:
- Jetpack. Its connection to WordPress.com uses XML-RPC. Blocking the file breaks Jetpack's features, from stats to backups. If you run Jetpack, rate-limit instead of blocking.
- Mobile and desktop publishing apps. Older versions of apps that post to self-hosted WordPress, and some desktop blog editors, log in through XML-RPC. Current apps increasingly use the REST API with an application password; check the app's own documentation.
- Remote management and publishing services. Some site-management dashboards, cross-posting tools and older integrations call XML-RPC. Check the settings of anything that logs in to your site from outside.
- Pingbacks and trackbacks. If you want other blogs' pingbacks to appear as comments, XML-RPC must stay on. Most sites turn pingbacks off anyway under Settings → Discussion.
The quickest way to know is your access log. Search it for xmlrpc.php and look at where the requests come from:
# Requests to xmlrpc.php in the last log, grouped by client IP
grep "xmlrpc.php" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | headRequests from your own office, Jetpack's servers or a service you use are legitimate. Requests from hundreds of unrelated addresses, all POST, are bots.
How to disable XML-RPC in WordPress
There are three levels, from most to least effective. Use one.
1. Block the file at the server
This stops every XML-RPC request before PHP runs, including pingbacks. It is the right choice when nothing on the list above applies.
# nginx, inside the server block for the site
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}# .htaccess in the WordPress folder (Apache 2.4)
<Files "xmlrpc.php">
Require all denied
</Files>Reload nginx (sudo nginx -t && sudo systemctl reload nginx) after the change. On Apache the .htaccess rule applies straight away. If you have to allow one service, nginx can allow its addresses above deny all; get the list from the service's documentation.
2. Block or rate-limit it at the CDN
On Cloudflare, a custom WAF rule does the same job at the edge, so the request never reaches your host. In Security → WAF → Custom rules, create a rule with this expression and the action Block:
(http.request.uri.path eq "/xmlrpc.php")If Jetpack or an app needs XML-RPC, use a rate limiting rule on the same path instead, for example more than 5 requests in 1 minute from one IP address leads to a block for 10 minutes. Rate limiting and bot protection on a small site covers the thresholds, and Cloudflare settings for speed and security the rest of the dashboard.
3. Switch it off inside WordPress
When you cannot change the server or CDN, a must-use plugin can turn XML-RPC off from inside WordPress. Requests still reach PHP, so it saves no server capacity, but they are refused. The xmlrpc_enabled filter alone only disables methods that need a login; WordPress's own documentation for the filter says it does not control pingbacks. Remove the pingback methods as well:
<?php
// wp-content/mu-plugins/disable-xmlrpc.php
// Refuse every XML-RPC method that needs a login.
add_filter( 'xmlrpc_enabled', '__return_false' );
// Remove the methods that work without a login.
add_filter( 'xmlrpc_methods', function ( $methods ) {
unset( $methods['pingback.ping'], $methods['pingback.extensions.getPingbacks'] );
return $methods;
} );
// Stop advertising the pingback endpoint in the X-Pingback header.
add_filter( 'wp_headers', function ( $headers ) {
unset( $headers['X-Pingback'] );
return $headers;
} );Files in wp-content/mu-plugins/ load automatically, cannot be deactivated from the Plugins screen and survive theme changes. Many security plugins have a "Disable XML-RPC" switch that does something similar; check whether it also covers pingbacks.
How to check that XML-RPC is off
Send a harmless request that lists the available methods:
curl -s -o /dev/null -w "%{http_code}\n" -X POST \
-H "Content-Type: text/xml" \
--data '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>' \
https://example.com/xmlrpc.php- 403 or 404: the server or CDN blocks the file. XML-RPC is off.
- 200: the file answers. Drop the
-o /dev/null -w …part to read the response: with the must-use plugin above,pingback.pingis missing from the list, and a method that needs a login returns the fault "XML-RPC services are disabled on this site". - 405 on a GET: normal. Visiting
xmlrpc.phpin a browser shows "XML-RPC server accepts POST requests only" whether or not it is protected, so a browser test proves nothing.
Then check that what you rely on still works: Jetpack's connection status under Jetpack → Dashboard, a test post from your app, a pingback if you use them.
What getReport checks
The WordPress security scan recognises WordPress from the page, including the xmlrpc.php link in the head, and checks the public signs attackers combine with XML-RPC: an exposed "admin" login name and an outdated WordPress version.
A dedicated check for an open xmlrpc.php is planned for the WordPress Doctor. It needs to send a POST request, which the report's request guard does not do yet. When it ships, it will show a plain yes or no to anyone who runs the report, and the details only to the site's verified owner, like the other sensitive WordPress checks.
Common mistakes
- Deleting
xmlrpc.php. The next core update restores it, and until then some plugins may fatal-error. Block it instead. - Relying on the
xmlrpc_enabledfilter alone. Password guessing stops, pingback abuse does not. Add thexmlrpc_methodsfilter, or block the file. - Blocking it with Jetpack active. Jetpack disconnects and its features stop. Rate-limit instead.
- Installing a plugin just for this. Two lines of server config or one must-use file do the job without another plugin to update.
- Protecting XML-RPC but not the login. The same bots try
wp-login.php. Rate-limit both and turn on two-factor login, as in WordPress login security.
Questions people ask
Should I disable XML-RPC in WordPress?
Yes, unless something uses it. XML-RPC (/xmlrpc.php) is an old remote API that attackers use for password guessing and pingback abuse. The block editor and the REST API do not need it; Jetpack and some mobile apps and remote publishing tools do. Block it at the server or CDN, or with a must-use plugin, then check that nothing you rely on stopped working.
Can I delete xmlrpc.php?
No. It is a WordPress core file, and every core update puts it back, sometimes within hours through automatic updates. Deleting it also triggers integrity warnings in security scanners. Block access to it in nginx, Apache or your CDN instead, which has the same effect for visitors and bots and survives updates.
Why is xmlrpc.php getting so many requests?
Because bots try it on every WordPress site they find. Most of the POST /xmlrpc.php lines in an access log are password guesses or pingback requests from many different addresses. They cost server capacity even when they fail. If you do not use Jetpack or an app that needs XML-RPC, block the file at the server or CDN and the requests stop reaching WordPress.
Does Jetpack need XML-RPC?
Yes. Jetpack's connection between your site and WordPress.com uses XML-RPC, so blocking xmlrpc.php breaks its features. If you run Jetpack, keep the endpoint open and protect it with a rate limit at your CDN or server instead, and make sure every administrator uses two-factor login so guessed passwords are worthless.
What does "XML-RPC server accepts POST requests only" mean?
It means you opened xmlrpc.php in a browser, which sends a GET request, and the file answered that it only takes POST. It is normal and says nothing about whether XML-RPC is protected. Test with a POST request, for example with the curl command in this guide: a 403 or 404 means the file is blocked.