HostleloBlog
SavedSearch
Visit Hostlelo

Disable WordPress XML-RPC Safely Without Breaking Apps

Check whether Jetpack or a mobile app needs xmlrpc.php, then block or rate-limit it at the server and prove the change worked with a single curl command.

The short answer

First check whether Jetpack, a mobile app or a remote publishing tool uses xmlrpc.php. If nothing does, block the file at the web server with a Files block in .htaccess or a deny rule in Nginx, so it returns 403 Forbidden. If you do need it, keep it open and rate-limit it instead. A plugin toggle or the xmlrpc_enabled filter alone only switches off authenticated methods.

Reading options

On this page

You can turn off WordPress XML-RPC safely, but only after you confirm nothing on your site depends on it. Jetpack and some mobile or remote publishing apps talk to your site through xmlrpc.php, so blocking it blindly can break them without any warning on the front end.

Here is the part most guides skip: a plugin toggle can switch off only some XML-RPC methods, while the file itself still answers every request that reaches it. If you want the door actually closed, you close it at the web server, before WordPress even loads.

By the end of this guide you will know whether you need XML-RPC, how to switch it off in code or block it at the server, how to rate-limit it if you must keep it, and how to prove the change worked.

What is XML-RPC, and why do attackers like it?

XML-RPC is an old way for other programs to talk to WordPress. RPC means "remote procedure call": an outside app sends a small XML message to xmlrpc.php saying "please run this action", for example "publish this post", and WordPress replies.

Think of it as a side door at the back of a shop. The front door is your normal login page at wp-login.php, with all the security you have set up. The side door was built so delivery drivers (apps) could drop things off without walking through the shop. It is useful, but if nobody delivers through it any more, it is just another door someone can rattle all night.

Why this matters: the official WordPress brute-force guide says plainly that xmlrpc.php is a frequent brute-force target, especially the system.multicall method. A brute-force attack is a bot guessing usernames and passwords again and again until one works.

The same guide gives simple advice: if you do not use XML-RPC, disable it; if you do, for example for Jetpack or mobile apps, restrict it and rate-limit it aggressively. That is exactly the decision you will make in the next section.

Before you start

Give yourself about 20 to 30 minutes. The risk is low if you take a backup first, because every change below can be undone by deleting a few lines.

  • Access: your hosting control panel file manager (cPanel, Plesk, DirectAdmin) or SFTP, or SSH if you run your own server.
  • Backup: download a copy of your current .htaccess file, or your Nginx site config, before you touch it.
  • Tools: a terminal with curl for testing, or any online HTTP header checker if you do not have one.
  • Jetpack: check WordPress admin > Plugins for Jetpack. If it is active and you use its features, do not fully block XML-RPC.
  • Mobile apps: ask yourself and your team whether anyone writes or edits posts from a phone app.
  • Remote publishing tools: check for desktop blog editors, publishing services, or old integrations that post to the site.
  • Risk level: low for the code route, low to medium for server edits, because a typo in .htaccess can take the whole site down until you fix it.

Quick tip: if you are not sure whether anything uses XML-RPC, look at your access logs for POST requests to /xmlrpc.php. If every request comes from random IP addresses you do not recognise and nothing on your team publishes remotely, you very likely do not need it.

Invented example: Amina runs a small bakery site. She sees thousands of POST requests to xmlrpc.php each day in her logs, she does not use Jetpack, and she edits posts only from her laptop browser. She is a perfect case for a full server block.

Choose your route

There are three sensible options. Pick one based on what you found in the checklist.

  • Option A, code route: you want to stop logins and publishing through XML-RPC but leave the file reachable.
  • Option B, server route: you do not need XML-RPC at all and want the file blocked before PHP runs.
  • Option C, rate-limit: you need XML-RPC for Jetpack or an app, so you keep it open but slow down abusers.

Option A: switch off authenticated methods in code

WordPress has a filter called xmlrpc_enabled. The developer reference describes it as one that "Filters whether XML-RPC methods requiring authentication are enabled." Its default value is true, and it was introduced in WordPress 3.5.0.

Heads up: despite the name, this filter does not switch XML-RPC off completely. The reference explains that it only controls methods that need a login, such as publishing. It does not control pingbacks or other custom endpoints that do not need authentication, and the file still loads PHP for every request.

Step 1: create a must-use plugin file

A must-use plugin is a PHP file WordPress loads automatically from wp-content/mu-plugins. According to the WordPress documentation, it is enabled on its own, cannot be disabled from wp-admin, and appears in a separate Must-Use section instead of the default plugin list. That makes it a good home for a small security rule, because nobody can turn it off by accident.

Open your file manager or SFTP, go to wp-content, and create a folder called mu-plugins if it does not exist. Inside it, create a file called disable-xmlrpc-auth.php. WordPress only loads PHP files sitting directly in that folder, not in subfolders.

Step 2: add the filter

Paste the following code into the new file; it tells WordPress to refuse every XML-RPC method that requires a username and password.

<?php
/**
 * Plugin Name: Disable XML-RPC authenticated methods
 */
add_filter( 'xmlrpc_enabled', '__return_false' );

Save the file. Go to WordPress admin > Plugins and you should see a separate Must-Use section with this plugin listed.

Step 3: decide whether you need more

If you also want to remove specific methods, WordPress has a second filter, xmlrpc_methods, which the reference says "can be used to add new methods, and remove built-in methods." It receives an array of methods keyed by their method name. This is developer territory, so if you need it, hand it to whoever maintains your theme or plugins.

Why this matters: Option A still lets bots reach xmlrpc.php and start PHP on every hit. If your logs show heavy traffic, Option B saves server resources as well.

Option B: block xmlrpc.php at the server

This is the route I recommend when nothing on your site needs XML-RPC. The web server refuses the request with 403 Forbidden before WordPress starts, so there is nothing for a bot to guess against.

The Apache documentation says a <Files> section matches a file by its base name and can be used in .htaccess when the server's AllowOverride setting allows it. The Require all denied line, from Apache's authorization module, means access is denied unconditionally.

Step 1: open your .htaccess file

Your .htaccess file sits in the WordPress root folder, the same folder that holds wp-config.php and xmlrpc.php. On most shared hosting that is public_html.

The file name starts with a dot, so many file managers hide it. The cPanel steps are in the variants section below.

Step 2: add the block outside the WordPress section

Look for the lines # BEGIN WordPress and # END WordPress. WordPress rewrites everything between those markers when you save permalinks, and the WordPress hardening guide advises keeping your own protections outside those WordPress-managed tags.

Add the following block below # END WordPress (or above # BEGIN WordPress); it denies every request for xmlrpc.php, whatever method or IP address it comes from.

<Files "xmlrpc.php">
Require all denied
</Files>

Save the file. Make sure both the opening and closing lines are there, because a missing </Files> line breaks the whole site.

Step 3: test straight away

Keep the editor open and test from your terminal. The full checks are in "How to check it worked" below. If anything goes wrong, delete the three lines and save, and you are back where you started.

I tested this exact block on a fresh Apache 2.4 server. With AllowOverride All, xmlrpc.php returned HTTP/1.1 403 Forbidden and the home page still returned 200 OK. With AllowOverride None, the block was silently ignored and the file still returned 200 OK, which is the most common reason this rule "does nothing".

Option C: keep XML-RPC but rate-limit it

If Jetpack or a mobile app needs XML-RPC, do not block it. Instead, follow the WordPress brute-force guide and rate-limit it, so one IP address can only make a small number of requests per minute. This option needs Nginx and access to its configuration, which usually means a VPS or a managed server where you can ask the host.

Step 1: add a rate-limit zone

The following line, adapted from the official WordPress brute-force guide, creates a shared memory zone called logins that allows each client IP address 10 requests per minute. It goes in the http block of your Nginx configuration.

limit_req_zone $binary_remote_addr zone=logins:10m rate=10r/m;

Step 2: apply it to xmlrpc.php

Inside your site's server block, the following location applies that limit to xmlrpc.php, allowing a short burst of 20 requests before the limit kicks in, and then passes the request to PHP as usual.

location = /xmlrpc.php {
    limit_req zone=logins burst=20 nodelay;
    include fastcgi_params;
    # pass to PHP-FPM or upstream as usual
}

Replace the comment line with the same PHP handling lines your other .php locations already use. The guide also suggests applying the same limit to /wp-login.php.

Step 3: test and reload

Run the following command to check the configuration for syntax errors before you reload.

sudo nginx -t

You should see a line ending in test is successful. Then reload Nginx using your usual method, for example sudo nginx -s reload.

Step 4: confirm Jetpack and apps still work

Jetpack's support page says Jetpack needs xmlrpc.php to connect to your site. At the time of writing (24 October 2026), it suggests visiting https://example.com/xmlrpc.php in your browser, where you should see exactly XML-RPC server accepts POST requests only. on its own.

Then check WordPress admin > Tools > Site Health for Jetpack connection notes, and run the Jetpack Debug Tool described on its troubleshooting page. A passing result shows "Everything looks great!" For a mobile app, open it, make a small draft, and save it.

Variants by panel and server

The rule itself is the same everywhere Apache-style .htaccess files work. What changes is how you open the file.

cPanel: File Manager

  1. Log in and open File Manager in cPanel.
  2. Click Settings in the top right, tick Show Hidden Files (dotfiles), and click Save.
  3. Open public_html (or the folder your WordPress lives in).
  4. Select .htaccess and click Edit.
  5. Add the block from Option B below # END WordPress and save the file.

Quick tip: cPanel's documentation notes that File Manager cannot edit files larger than 1 MB. A normal .htaccess is far smaller, but if yours is huge, download it and edit it locally.

Plesk

The Plesk customer guide opens the file manager from Websites & Domains > your domain > File Manager. Find .htaccess in your site's document root, open its menu, and choose one of the Edit in ... Editor options; the plain text editor is the safest. The exact layout depends on your Plesk version, so if the menus look different, search Plesk's help for "File Manager".

Heads up: always run the curl test below after saving, because the test result is what counts, not the file.

DirectAdmin

Use the file manager inside DirectAdmin, or SFTP, to open .htaccess in your WordPress root folder, then add the Option B block. If you cannot see the file, it is hidden because of the leading dot, so look for a "show hidden files" setting or use SFTP.

Nginx

Nginx does not read .htaccess at all, so Option B does nothing there. Instead, the following location block inside your server block refuses every request for xmlrpc.php; the deny directive comes from the Nginx access module and is allowed in a location block.

location = /xmlrpc.php {
    deny all;
}

Run sudo nginx -t and reload. On my test server this returned HTTP/1.1 403 Forbidden for both GET and POST requests. Make sure the block sits inside the server block for the right domain.

LiteSpeed

LiteSpeed's documentation says it reads Apache-style directives and .htaccess files, and that AllowOverride is supported. It also warns that some Apache modules and directives are not supported. So add the same Option B block, then run the curl test to confirm LiteSpeed honours it on your server.

How to check it worked

Testing takes two minutes and saves you from false confidence. Replace example.com with your own domain.

Check 1: xmlrpc.php is blocked

The following command asks your server for just the response headers of xmlrpc.php.

curl -I https://example.com/xmlrpc.php

After Option B or the Nginx block, the first line should show a 403 status, like this result from my Apache test:

HTTP/1.1 403 Forbidden

The 403 status code is the part that matters. If you see 200 or anything other than 403, the request is still getting through, so jump to Troubleshooting.

Check 2: the rest of the site still works

The following command checks the response headers for your home page.

curl -I https://example.com/

You should see a 200 status, or a 301 or 302 redirect if your site redirects to another address. Then log in at https://example.com/wp-admin/ in a private browser window, open a post, and save a draft. If all of that works, you are done.

Troubleshooting

The rule had no effect, xmlrpc.php still returns 200

Symptom: curl -I still shows 200 OK after you saved .htaccess. Likely cause: the server's AllowOverride is set to None, so Apache ignores .htaccess entirely; I reproduced exactly this on a test server. Fix: on your own server, allow overrides for your site's directory in the main Apache config and reload Apache. On shared hosting, ask your host, or check that you edited the .htaccess in the right folder.

500 Internal Server Error after editing .htaccess

Symptom: every page shows 500 Internal Server Error. Likely cause: a typo, such as a missing </Files> line. On my test server, the Apache error log showed <Files> was not closed. for exactly this mistake. Fix: open the file again, correct or remove the block, save, and reload the page. This is why you took a backup.

Jetpack stopped syncing or shows a connection error

Symptom: Jetpack shows errors such as "XML-RPC is not responding correctly" or a notice that "WordPress.com requests to your site are being blocked". Likely cause: your server block or a security rule now refuses xmlrpc.php. Fix: remove the full block and use Option C instead. Jetpack's support page suggests asking your host to allow xmlrpc.php requests from Jetpack's IP addresses, and says Jetpack rechecks once a day, so the notice can take up to a day to clear after the block is removed.

A mobile app cannot publish

Symptom: the app says it cannot reach your site or cannot log in, even with the correct password. Likely cause: the app uses XML-RPC, and Option A or Option B now refuses it. Fix: remove the block, or switch to Option C. Some tools may offer to connect through the REST API with an application password instead; our guide to WordPress application passwords and the REST API explains how that works.

The plugin toggle is on but bots still hit xmlrpc.php

Symptom: your logs still show many POST requests to xmlrpc.php. Likely cause: a plugin that relies on the xmlrpc_enabled filter only switches off authenticated methods; the file still answers. Fix: use Option B or the Nginx block, so the server refuses the request before PHP runs.

Nginx block does nothing

Symptom: xmlrpc.php still returns 200 on an Nginx server after you added the deny all; block. Likely cause: you edited a config that is not loaded, or you forgot to reload. Fix: run sudo nginx -t, reload, and confirm the block sits inside the server block for the right domain.

Pro tips and security notes

  • Blocking XML-RPC closes one door. Protect the main one too: add two-factor authentication to your hosting panel and your WordPress admin accounts.
  • Keep all your own .htaccess rules together outside the WordPress markers, with a short comment saying what each one does and when you added it.
  • If you are already editing .htaccess, it is a good moment to review your HSTS and security headers.
  • On a VPS, a tool such as Fail2ban can ban IP addresses that keep hammering your server; see our guide to Fail2ban SSH protection on a VPS for the basics.
  • Write down any exceptions your site needs, such as Jetpack or a mobile app. The WordPress brute-force guide recommends documenting these before applying server-level blocks.

Ask your host or a developer when you cannot see or edit .htaccess, when your server uses Nginx and you have no access to its configuration, when the rule has no effect and you suspect AllowOverride, or when you need Jetpack and want firewall rules that allow only its traffic.

The one message worth forwarding

If you would rather someone else made the change, copy this and send it to your developer or hosting support:

"Hi, please help me secure xmlrpc.php on my WordPress site at example.com. We [do / do not] use Jetpack, mobile apps or remote publishing tools. If we do not, please block xmlrpc.php at the web server so it returns 403 Forbidden (for Apache or LiteSpeed, a <Files "xmlrpc.php"> block with Require all denied outside the WordPress section of .htaccess; for Nginx, a location = /xmlrpc.php block with deny all;). If we do, please keep it open but rate-limit it as described in the WordPress brute-force guide. Please confirm with curl -I https://example.com/xmlrpc.php and check that wp-admin login still works. Thank you."

The takeaway: check what depends on XML-RPC first, then block or rate-limit it at the server and prove it with one curl command.

Reader questions

Is it safe to delete xmlrpc.php instead of blocking it?

Blocking is the better choice. Jetpack's support page says Jetpack needs xmlrpc.php to connect, and a server rule is easy to undo by deleting a few lines.

Does a security plugin toggle fully disable XML-RPC?

Not always. A toggle that relies on the xmlrpc_enabled filter affects only methods that need a login, as WordPress documents, so the file still answers other requests.

Will blocking XML-RPC stop pingbacks?

A server-level block refuses every request to the file, so pingbacks sent to it stop as well. The code filter alone leaves pingbacks working.

How do I know if Jetpack can still reach my site?

Open your xmlrpc.php address in a browser and look for the exact text that it accepts POST requests only, then check Site Health and the Jetpack Debug Tool.

My host uses Nginx. Can I still use .htaccess?

No. Nginx ignores .htaccess files, so you need a location rule in the Nginx site configuration, or you can ask your host to add it.

What status code should a blocked xmlrpc.php return?

With the Apache or Nginx rules in this guide, the server answers 403 Forbidden. A 200 response means the request is still getting through.

Can I undo the change if something breaks?

Yes. Remove the block you added, or delete the must-use plugin file, then save and test again. Keeping a backup copy of the original file makes this quicker.

Sources & further reading

  1. WordPress Developer Reference: xmlrpc_enabled hook
  2. WordPress Developer Reference: xmlrpc_methods hook
  3. WordPress Advanced Administration: Brute Force Attacks
  4. WordPress Advanced Administration: Must Use Plugins
  5. Apache HTTP Server 2.4: core features
  6. Apache HTTP Server 2.4: mod_authz_core
  7. Nginx: ngx_http_access_module
  8. Jetpack: Fix Jetpack Issues
  9. cPanel Documentation: File Manager
  10. LiteSpeed Web Server: Configuration

Originally published . About our editorial updates.

Your next project deserves a better foundation.

Explore hosting built for your next chapter.

Explore hosting

Find your next answer.

Search published guides and articles.

Ctrl / ⌘ K to open · Esc to close