WordPress self-pingbacks are automated pingback notifications that can be created when one post on your website links to another post on the same WordPress installation.
For example:
Post A
↓
links to
↓
Post B
on the same website
The internal link itself is useful.
But WordPress can also process that URL through its pingback system, effectively causing the website to notify itself that one of its own posts linked to another.
The result can appear in WordPress as a comment-like pingback entry on the destination post.
This is called a:
self-pingback
or
self-ping
Self-pingbacks are not the same thing as internal links.
They are also not the same as:
- normal comments;
- trackbacks;
- external pingbacks;
- XML-RPC as a whole;
- REST API requests.
The useful mental model is:
Internal link
→ part of your content
Pingback
→ automated notification about a link
Self-pingback
→ that notification happens between URLs
on your own site
This guide explains how WordPress self-pingbacks work, when they are created, how WordPress discovers pingback endpoints, how they interact with XML-RPC and Discussion Settings, why they can become administrative noise and how to stop them without removing your internal links or unnecessarily disabling unrelated functionality.
Quick answer
A self-pingback can happen when:
Post A contains a full URL
pointing to Post B
on the same WordPress site
+
outgoing pingbacks are enabled
+
WordPress processes the link
+
the destination can receive pingbacks
The resulting notification may be stored on Post B as a pingback-style comment.
If you want to keep internal links but prevent only the self-pingback process, WordPress provides:
pre_ping
which runs before WordPress processes outgoing pingback destinations.
A typical solution removes same-site URLs from that queue:
function project_disable_self_pingbacks(
&$post_links
) {
$home_url =
home_url( '/' );
foreach (
$post_links as $key => $link
) {
if (
str_starts_with(
$link,
$home_url
)
) {
unset(
$post_links[ $key ]
);
}
}
}
add_action(
'pre_ping',
'project_disable_self_pingbacks'
);
This preserves:
internal hyperlink
→ yes
self-pingback
→ no
external pingbacks
→ still possible
XML-RPC
→ unchanged
The complete implementation strategy is covered in Disable Self-Pingbacks Without Disabling XML-RPC.
What is a pingback?
A pingback is an automated notification sent between websites when one page links to another page and both sides support the pingback mechanism.
The official WordPress Trackbacks and Pingbacks documentation describes pingbacks as automated link notifications that can appear in the receiving site’s comments system.
Basic external pingback example
Suppose:
site-a.com/article/
↓
contains a link to
↓
site-b.com/guide/
If pingbacks are enabled and supported:
Site A
↓
detects the link
↓
discovers Site B's
pingback endpoint
↓
sends pingback.ping
↓
Site B verifies the source
↓
Site B may store
a pingback comment
What makes a pingback a self-pingback?
The process becomes a self-pingback when both URLs belong to the same site.
For example:
https://example.com/wordpress-security/
links to
https://example.com/wordpress-backups/
The source and destination are both:
example.com
so WordPress can end up notifying:
example.com
→ about a link from example.com
→ to example.com
Example of a real self-pingback workflow
Imagine you publish:
How to Secure WordPress
and include:
<a href="https://example.com/wordpress-backups/">
WordPress backups
</a>
WordPress can process that absolute URL as a pingback destination.
The destination article:
WordPress Backups
may then receive a pingback representing the first article.
In the comments area you might see something conceptually resembling:
Pingback:
How to Secure WordPress
The internal link and the pingback are separate things
This distinction matters more than anything else in this guide.
The internal link exists inside:
post_content
The self-pingback is generated later by WordPress’s publishing and notification workflow.
You can therefore have:
internal link
→ preserved
self-pingback
→ disabled
without weakening your internal linking strategy.
See Pingbacks, Trackbacks & Internal Links for the broader relationship between the three systems.
Why WordPress creates self-pingbacks
WordPress’s pingback system is designed around URLs, not around the editorial intention behind each link.
When WordPress processes a post, Core can extract URLs from its content.
The relevant function is:
pingback()
The official pingback() documentation describes it as the function that pings back links found in a post.
WordPress extracts URLs from the post
Inside the current Core implementation:
wp_extract_urls()
is used to identify URLs present in the post content.
Conceptually:
post_content
↓
wp_extract_urls()
↓
candidate URL list
WordPress removes some obvious non-candidates
Core performs several checks before a URL enters the final ping list.
For example, it avoids:
- URLs already pinged by the post;
- a URL resolving to the same post itself;
- local attachment URLs;
- certain root-level URLs that do not point to a specific resource.
But another post on the same site can remain eligible
Consider:
Current post ID
→ 100
linked internal post ID
→ 200
The destination is not:
the same post
so it can remain in the outgoing list.
That is how a legitimate internal relationship can become a self-pingback candidate.
WordPress does not automatically remove every same-site URL
Core prevents a post from pinging itself directly.
That is different from preventing:
Post A
→ Post B
on the same domain
This is the behavior addressed by self-pingback filtering.
WordPress tracks URLs that have already been pinged
The current Core implementation retrieves:
get_pung()
before processing candidate URLs.
This contains URLs that the post has already successfully pinged.
Why?
Without this record, repeatedly updating the same post could repeatedly notify the same destination.
Conceptually:
new URL
→ eligible
already pinged URL
→ skip
Successful ping destinations are recorded
After a successful pingback, WordPress can use:
add_ping()
to record the destination against the source post.
Self-pingbacks can therefore appear only once for a given source-destination relationship
That can sometimes make the behavior seem inconsistent.
You may update a post and see:
no new self-pingback
simply because WordPress already recorded that destination as pinged earlier.
How publishing triggers pingback processing
WordPress does not need to perform every pingback operation directly inside the main post-save request.
Core’s publishing workflow can mark a published post for ping processing and schedule the:
do_pings
event.
When outgoing pingbacks are enabled, WordPress can add:
_pingme
post metadata.
do_all_pingbacks() processes those posts
The official do_all_pingbacks() documentation shows that WordPress:
finds posts with _pingme
↓
removes the marker
↓
calls pingback()
for each one.
This explains why pingback behavior is part of the publishing workflow
The sequence is approximately:
publish post
↓
post marked for ping processing
↓
do_pings event
↓
do_all_pingbacks()
↓
pingback()
↓
extract URLs
↓
filter candidates
↓
pre_ping
↓
discover endpoints
↓
send pingbacks
Where pre_ping fits
The:
pre_ping
action runs after WordPress has built the candidate list but before it starts contacting those destinations.
The official pre_ping documentation states that it fires immediately before pinging back links found in a post.
WordPress passes three values
$post_links
$pung
$post_id
where:
$post_links
→ URLs about to be checked
$pung
→ URLs already pinged
$post_id
→ source post ID
The first two arrays are passed by reference
This allows a plugin to modify them directly.
For self-pingback removal:
$post_links
→ inspect each destination
→ remove local destinations
Why pre_ping is ideal for self-pingbacks
At this point:
- the internal link is already stored normally;
- WordPress has already extracted candidate URLs;
- the pingback has not yet been sent;
- remote endpoint discovery has not yet completed for the filtered URL.
This gives you a clean interception point.
What happens after pre_ping?
For every URL that remains in the queue, WordPress calls:
discover_pingback_server_uri()
The official discover_pingback_server_uri() documentation describes how WordPress tries to find a pingback server endpoint for the target URL.
WordPress first checks the HTTP headers
The current implementation sends a HEAD request and checks for:
X-Pingback
If necessary, WordPress examines the HTML
If the header does not provide the endpoint, WordPress can fetch the page and look for:
rel="pingback"
inside the document markup.
Example pingback discovery link
<link
rel="pingback"
href="https://example.com/xmlrpc.php"
/>
Once discovered, WordPress sends an XML-RPC request
The current Core pingback() implementation creates an XML-RPC client and invokes:
pingback.ping
with:
source URL
+
destination URL
Self-pingback sequence in detail
Post A
https://example.com/post-a/
contains:
https://example.com/post-b/
↓
WordPress extracts URL
↓
post-b remains eligible
↓
pre_ping runs
↓
if no self-ping filter exists,
post-b remains
↓
WordPress requests post-b
↓
discovers pingback endpoint
↓
https://example.com/xmlrpc.php
↓
WordPress sends pingback.ping
↓
source:
https://example.com/post-a/
destination:
https://example.com/post-b/
↓
the same WordPress site
receives the request
↓
destination validates source
↓
pingback may be stored
against Post B
This is why self-pingbacks feel redundant
Your server can effectively perform:
outbound HTTP request
↓
to itself
↓
discover itself
↓
call its own XML-RPC endpoint
↓
verify one of its own pages
↓
store a notification
about its own internal link
There are historical reasons for the generic architecture, but on a modern content-heavy site the result often provides very little editorial value.
How the receiving side works
A pingback is not blindly accepted simply because another site sends:
pingback.ping
The receiving WordPress installation performs validation.
It receives:
source URL
destination URL
and verifies the relationship before registering the notification.
The destination can reject the pingback
Possible reasons include:
- pingbacks are disabled for the destination;
- the destination URL is invalid;
- the source URL cannot be verified;
- the pingback already exists;
- the request is blocked by another security or discussion policy.
A self-pingback is still processed as a real pingback
WordPress does not conceptually say:
"This came from myself,
so create a special
self-pingback object."
It goes through the normal pingback architecture with the unusual circumstance that source and destination belong to the same site.
Where self-pingbacks appear in WordPress
Pingbacks are part of WordPress’s discussion system.
They can therefore appear alongside comment-related data in wp-admin.
A typical administration workflow may show:
Comments
John:
Great article
Pingback:
Related WordPress Security Guide
Spam comment:
Buy suspicious things now
because human comments, pingbacks and trackbacks all participate in the broader discussion architecture.
Pingbacks are not normal human comments
A human comment is created by a person submitting a comment form or equivalent interface.
A pingback is generated by site-to-site link notification.
The difference is:
Comment
→ person submits discussion content
Pingback
→ another resource reports a link
WordPress stores them differently by comment type
The database can distinguish:
comment
pingback
trackback
even though they can all appear through related administration interfaces.
Self-pingbacks are not trackbacks
Pingbacks and trackbacks both originated as ways for websites to notify one another about links.
They are not identical.
The official WordPress documentation summarizes the distinction as:
Pingback
→ automatic
Trackback
→ manually initiated legacy notification
Trackbacks can include an excerpt
Traditional trackbacks send information such as:
- source URL;
- title;
- blog name;
- excerpt.
Pingbacks operate differently
The receiving site verifies the source link rather than trusting an excerpt provided by the sender.
A self-pingback is specifically a pingback phenomenon
When this guide refers to:
self-ping
it means an automated pingback from one URL on your site to another URL on that same site.
Self-pingbacks and XML-RPC
Pingbacks are closely connected to WordPress XML-RPC.
The standard XML-RPC endpoint is:
https://example.com/xmlrpc.php
WordPress exposes pingback XML-RPC methods
These include:
pingback.ping
pingback.extensions.getPingbacks
through the XML-RPC server.
This does not mean XML-RPC and self-pingbacks are the same setting
They are different layers.
XML-RPC
→ remote communication interface
pingback.ping
→ one XML-RPC method
self-pingback
→ one specific scenario
involving the pingback system
You can disable self-pingbacks without disabling XML-RPC
Filtering:
pre_ping
does not make:
/xmlrpc.php
unavailable.
It only changes which outgoing URLs reach the later pingback stages.
See Disable Self-Pingbacks Without Disabling XML-RPC for the implementation.
Do not misunderstand xmlrpc_enabled
A very common snippet is:
add_filter(
'xmlrpc_enabled',
'__return_false'
);
It is frequently described as:
disable all XML-RPC
but that description is incomplete.
The official xmlrpc_enabled documentation states that it controls XML-RPC methods requiring authentication.
It specifically does not automatically disable:
pingbacks
and
other unauthenticated custom endpoints
This matters when diagnosing self-pingbacks
If somebody adds:
xmlrpc_enabled = false
and expects:
all pingback behavior
→ gone
that assumption is unreliable.
XML-RPC method control is separate again
WordPress provides:
xmlrpc_methods
for modifying the methods exposed by the XML-RPC server.
The official xmlrpc_methods documentation says that built-in methods can be removed from the registered method array.
Example
function project_remove_pingback_methods(
$methods
) {
unset(
$methods['pingback.ping']
);
unset(
$methods[
'pingback.extensions.getPingbacks'
]
);
return $methods;
}
add_filter(
'xmlrpc_methods',
'project_remove_pingback_methods'
);
But that addresses a different requirement
Compare:
pre_ping
→ outgoing destination filtering
xmlrpc_methods
→ XML-RPC method availability
Keep the policies separate
A site might reasonably use:
self-pingbacks
→ disabled
external outgoing pingbacks
→ enabled
incoming pingbacks
→ enabled
other XML-RPC methods
→ enabled
or:
self-pingbacks
→ disabled
all pingbacks
→ disabled
XML-RPC publishing
→ still enabled
or:
all XML-RPC
→ blocked
pingback system
→ consequently unavailable
These are separate architectural choices.
For the wider protocol, see XML-RPC in WordPress, Explained.
For security and compatibility considerations, see What Is XML-RPC in WordPress, and Why Disable It?.
Which WordPress settings control pingbacks?
WordPress exposes relevant controls under:
Settings
→ Discussion
The official Discussion Settings documentation separates outgoing notifications from incoming link notifications.
Attempt to notify blogs linked from the article
The setting:
Attempt to notify any blogs
linked to from the article
controls the normal outgoing ping workflow.
If you disable it
You are not specifically saying:
disable self-pingbacks
You are saying more broadly:
do not attempt outgoing
link notifications
That can affect external pingbacks too
For example:
internal URL
→ no ping
external URL
→ no ping
This may be exactly what you want
If the site does not use outgoing pingbacks at all, disabling them broadly can be simpler than selectively filtering local URLs.
But it is different from self-pingback filtering
If you want:
internal URLs
→ no ping
external URLs
→ continue normal ping processing
then:
pre_ping
is a more targeted solution.
Incoming pingbacks have their own setting
WordPress also provides:
Allow link notifications
from other blogs
(pingbacks and trackbacks)
for new content.
This answers another question
Should this website
accept link notifications
from other websites?
It does not directly answer:
Should this website
ping itself?
WordPress discussion settings can be overridden per post
Site-wide Discussion Settings often act as defaults for new content.
Individual posts can have different:
ping_status
values.
This means old posts may behave differently
You can change the global setting today and still have historical content with:
pings = open
because its stored status was created earlier.
See WordPress Per-Post vs. Site-Wide Comment Settings.
Self-pingbacks and internal links
A common mistake is treating the self-pingback as evidence that the internal hyperlink itself is problematic.
It is not.
Internal links are part of normal website architecture
Good internal links can:
- connect related topics;
- help readers continue their journey;
- help crawlers discover pages;
- establish hierarchy;
- support topic clusters;
- provide contextual navigation.
The useful component is the hyperlink
Article about backups
↓
links to
↓
article about migrations
That relationship can be editorially valuable.
The self-pingback is optional metadata
The site does not need a second comment-like object merely to remember that the link exists.
Do not remove internal links to prevent self-pingbacks
This would be the wrong tradeoff:
remove useful internal navigation
↓
avoid minor admin notification
Relative URLs can sometimes avoid self-pings
The WordPress user documentation notes that a full absolute URL such as:
https://example.com/article/
can produce a self-ping, while a relative URL such as:
/article/
can avoid it.
Why?
WordPress’s pingback process extracts URLs from content.
A relative path does not look like the same complete remote URL that an absolute internal link does.
But rewriting your link strategy just for pingbacks is not ideal
There are several reasons:
- editors may normalize links;
- migration workflows may have specific URL requirements;
- content can be reused outside the original context;
- canonical-linking strategy should not be dictated by a legacy notification feature.
Use a pingback-specific solution when possible
Instead of changing:
every internal hyperlink
change:
the pingback queue
Do self-pingbacks affect SEO?
The internal hyperlink can matter to site navigation and search-engine crawling.
The self-pingback itself is not required for that relationship.
Disabling self-pingbacks does not remove link equity
If:
<a href="https://example.com/guide/">
related guide
</a>
remains inside the article, the internal hyperlink remains available to:
- users;
- search-engine crawlers;
- site analysis tools.
The pingback record is a separate object
Preventing it does not:
- add
nofollow; - remove the hyperlink;
- change the destination;
- change the anchor text;
- change the canonical URL.
Do not use self-pingbacks as an SEO linking strategy
Your internal-linking strategy should be based on useful contextual links.
A pingback entry in the comments system is not a substitute for good information architecture.
Do self-pingbacks affect performance?
Usually not in a way that should dominate a normal WordPress performance audit.
But self-pingbacks can trigger unnecessary work.
The processing can include
URL extraction
↓
candidate processing
↓
HTTP endpoint discovery
↓
server request
↓
XML-RPC processing
↓
source verification
↓
comment-like record creation
for a relationship that already exists entirely inside your own database and content.
Filtering the URL earlier avoids later ping processing
If an internal URL is removed at:
pre_ping
WordPress does not continue discovering and contacting the pingback endpoint for that URL.
Still, this is mainly workflow cleanup
Do not describe self-pingback removal as a major performance optimization.
The more accurate benefits are:
- less redundant notification processing;
- fewer unnecessary requests;
- cleaner discussion administration;
- clearer separation of internal links and pingbacks.
Do self-pingbacks affect security?
Stopping them removes an unnecessary same-site pingback path.
But it does not:
- disable XML-RPC;
- block external pingback requests;
- prevent authentication attacks;
- protect weak passwords;
- patch vulnerable plugins;
- replace rate limiting;
- replace a WAF.
Self-pingback removal is not complete XML-RPC hardening
The security model is:
self-pingback control
→ narrow behavior
XML-RPC hardening
→ broader interface policy
authentication security
→ separate again
Incoming pingbacks deserve their own security review
If you do not want external websites to call:
pingback.ping
against your WordPress installation, review incoming pingback configuration or XML-RPC method exposure separately.
Why self-pingbacks can clutter the comments screen
Consider a documentation-heavy site with:
500 articles
and extensive contextual linking.
If many new articles reference existing articles, self-pingbacks can create a stream of records such as:
Pingback:
Guide A
Pingback:
Guide B
Pingback:
Guide C
Pingback:
Guide D
mixed with genuine:
- reader comments;
- reviews;
- external pingbacks;
- spam.
This increases moderation noise
An editor may repeatedly review notifications that contain information already visible from the posts themselves.
Self-pingbacks can be useful in some workflows
They are not universally useless.
Some publishers may appreciate seeing which newer articles link back to an older post directly from that post’s discussion area.
Conceptually:
old article
↓
pingbacks show
↓
newer internal references
This was historically more meaningful in blog-centric workflows
When content and discussion architecture were heavily centered around chronological blog posts, pingbacks could function as a visible network of references.
Modern sites often have better tools for this information
Today, internal-link analysis can come from:
- SEO tools;
- site crawlers;
- editorial databases;
- internal-link reports;
- content-management tooling.
So the value of self-pingbacks depends on the workflow.
Should you disable WordPress self-pingbacks?
Disable them when:
- they create administrative clutter;
- your team does not use them;
- the site has extensive internal linking;
- you want external pingbacks to remain available;
- you want internal links preserved normally.
Keep them when they are genuinely useful
For example, a small blog may intentionally use pingbacks as visible references between posts.
There is no requirement to disable them merely because a plugin offers the option.
Decision model
Do self-pingbacks provide
useful editorial information?
│
├─ Yes
│ ↓
│ Keep them
│
└─ No
↓
Do you still need
external pingbacks?
│
├─ Yes
│ ↓
│ Filter only self-pingbacks
│
└─ No
↓
Consider disabling
outgoing pingbacks broadly
How to disable only self-pingbacks
Use:
pre_ping
to remove local destinations.
A minimal implementation is:
function project_disable_self_pingbacks(
&$post_links
) {
$home_url =
home_url( '/' );
foreach (
$post_links as $key => $link
) {
if (
str_starts_with(
$link,
$home_url
)
) {
unset(
$post_links[ $key ]
);
}
}
}
add_action(
'pre_ping',
'project_disable_self_pingbacks'
);
What the code changes
Before pre_ping:
[
https://example.com/internal-guide/,
https://external.example/article/
]
After pre_ping:
[
https://external.example/article/
]
What the code does not change
Inside the article:
<a href="https://example.com/internal-guide/">
Internal Guide
</a>
remains exactly where it was.
Why use home_url()?
WordPress provides:
home_url()
to retrieve the URL where the site’s frontend is accessible.
The official home_url() documentation describes this behavior.
For a conventional site it may return:
https://example.com/
Prefix matching is simple but exact
Consider:
home_url()
https://example.com/
linked URL
https://www.example.com/post/
Those strings do not begin identically.
A simple prefix implementation can therefore miss alternate host representations.
Common URL variations include
- HTTP vs HTTPS;
- www vs non-www;
- legacy domains;
- mapped domains;
- multilingual domains;
- reverse-proxy hostnames;
- subdirectory installations.
Canonical URL consistency helps
A WordPress site should ideally use one preferred URL representation consistently.
See WordPress Canonical URLs, Explained.
For domain or protocol changes, see How to Migrate WordPress URLs Safely.
Same host vs same WordPress site
A more advanced implementation might compare hostnames.
For example:
example.com/post-a/
example.com/post-b/
clearly share a host.
But consider:
https://example.com/blog/
https://example.com/shop/
They might belong to different applications under the same host.
Hostname matching can therefore be broader
You need to decide what:
self
means for your architecture.
Multisite makes the definition more complicated
Suppose a network contains:
site-a.example.com
site-b.example.com
A link between those sites may be:
internal to the network
but:
external to the individual site
There is no universal policy
You may want:
Site A
→ may ping Site B
because they operate as separate publications.
Or you may want:
all network sites
→ treated as internal
and suppress those notifications.
Test Multisite behavior deliberately.
How TheOneWP disables self-pingbacks
TheOneWP Disable Self Pingbacks uses the targeted WordPress pre_ping approach.
The verified implementation:
loads only when enabled
↓
hooks into pre_ping
↓
retrieves home_url()
↓
loops over outgoing URLs
↓
uses str_starts_with()
↓
removes matching local URLs
The module targets future outgoing self-pings
It does not:
- edit post content;
- remove internal links;
- change permalinks;
- disable XML-RPC;
- block external pingback destinations;
- disable trackbacks globally;
- delete existing pingback records.
External URLs remain in the queue
If the queue contains:
https://example.com/internal/
https://wordpress.org/documentation/
the internal URL is removed while the external URL remains available for normal WordPress processing.
The module does not add frontend code
It does not require:
- frontend JavaScript;
- CSS;
- REST routes;
- extra database tables;
- scheduled custom jobs.
It participates directly in the existing WordPress pingback pipeline.
How to test whether self-pingbacks are active
Use two controlled posts.
Step 1: create Post A
Self-Ping Test Source
Step 2: create Post B
Self-Ping Test Destination
Step 3: allow pings on Post B
This matters because a destination with pings already disabled cannot demonstrate whether outgoing self-ping filtering worked.
Step 4: add the full URL to Post A
<a href="https://example.com/self-ping-test-destination/">
Test destination
</a>
Step 5: publish or update Post A
Allow WordPress to process its outgoing pings.
Step 6: inspect the destination
Check:
Comments
or
destination discussion records
With normal self-ping behavior
You may see:
new pingback
from Post A
With a self-pingback filter
You should see:
internal link
→ works
self-pingback
→ not created
Do not reuse a destination already pinged during the test
Because WordPress tracks previously pinged URLs, reusing the same source-destination pair can give misleading results.
Use fresh test URLs when necessary
For example:
Post A → Post B
then
Post C → Post D
for a clean second test.
Existing self-pingbacks do not prove the filter failed
Check the timestamp.
A record created:
before the filter was enabled
will remain in the database.
Disabling future self-pingbacks does not delete history
This principle is:
future behavior
≠
stored historical data
See What Happens to Old Comments When You Disable Them.
How to remove old self-pingbacks
Historical cleanup is a separate operation.
You can review pingback entries through the WordPress comments administration area and remove selected records intentionally.
For larger cleanup operations
Before bulk deletion:
- create a database backup;
- distinguish pingbacks from normal comments;
- distinguish self-pingbacks from useful external pingbacks;
- test on staging;
- verify comment counts afterward.
Do not delete every comment-type record blindly
The comments system may also contain:
- real visitor comments;
- product reviews;
- plugin-specific comment data;
- external pingbacks;
- trackbacks.
Self-pingbacks and complete comment disabling
If your requirement is only:
stop my own posts
pinging one another
then complete comment disabling is excessive.
A complete comments shutdown can affect much more
Depending on implementation, it can affect:
- comment forms;
- existing discussions;
- product reviews;
- comment feeds;
- Dashboard widgets;
- admin menus;
- pingbacks;
- trackbacks.
See How to Completely Disable Comments in WordPress when the site’s actual policy is to remove discussion entirely.
Common mistake: deleting internal links
The internal link is not the problem.
The automated notification is the optional layer.
Common mistake: disabling XML-RPC just to remove self-pings
This can break unrelated functionality while solving a much narrower problem.
Common mistake: using xmlrpc_enabled as a complete XML-RPC shutdown
The filter controls authenticated XML-RPC methods, not every XML-RPC capability.
Common mistake: confusing incoming and outgoing pingbacks
These are different directions:
Outgoing
→ your site sends notification
Incoming
→ your site receives notification
Common mistake: confusing pingbacks with trackbacks
Pingbacks are automated. Trackbacks are a separate legacy mechanism.
Common mistake: assuming comments and pings share one switch
WordPress stores:
comment_status
separately from:
ping_status
Common mistake: changing the site-wide Discussion setting and expecting old posts to change
Existing posts can retain their stored per-post configuration.
Common mistake: using relative URLs purely as a workaround
Relative links can affect ping detection, but a pingback-specific hook is usually a cleaner architectural solution.
Common mistake: expecting pre_ping to delete existing pingbacks
It affects future outgoing processing only.
Common mistake: treating a historical self-ping as a new one
Always check dates and run a controlled fresh test.
Common mistake: testing with the same URL repeatedly
WordPress records destinations that have already been pinged.
Common mistake: assuming no pingback means your filter worked
The destination may simply have:
- pings disabled;
- no pingback endpoint;
- an XML-RPC restriction;
- a security rule blocking the request.
Common mistake: assuming an external pingback failure is caused by self-ping filtering
A remote destination controls whether it accepts and verifies the notification.
Common mistake: forgetting protocol changes
If the site migrated from:
http://example.com
to:
https://example.com
older absolute URLs may not match a simplistic current-home prefix.
Common mistake: forgetting www variants
Likewise:
www.example.com
and:
example.com
are different strings even if they ultimately resolve to the same site.
Common mistake: forgetting domain mapping
Multilingual and Multisite systems may legitimately use several public hostnames.
Common mistake: treating self-ping removal as a complete security control
It is a publishing-workflow adjustment, not a replacement for WordPress hardening.
Common mistake: treating self-ping removal as a major speed optimization
It removes unnecessary processing, but it is not equivalent to solving a slow database, poor caching or oversized frontend assets.
Common mistake: using several overlapping controls without documentation
A site might accidentally have:
Discussion outgoing pings
→ disabled
pre_ping filter
→ active
XML-RPC pingback methods
→ removed
server XML-RPC rule
→ active
security plugin
→ blocking requests
and nobody knows which one is responsible.
Document the policy
A maintainable configuration should make clear:
Self-pingbacks
→ enabled / disabled
External outgoing pingbacks
→ enabled / disabled
Incoming pingbacks
→ enabled / disabled
Trackbacks
→ enabled / disabled
XML-RPC
→ enabled / restricted / disabled
WordPress self-pingback checklist
- Understand that a self-pingback is not the same as an internal link.
- Keep useful internal links intact.
- Understand that pingbacks are automated link notifications.
- Understand that trackbacks are a separate legacy mechanism.
- Review Settings → Discussion.
- Check whether outgoing pingbacks are enabled.
- Check whether incoming pingbacks are enabled.
- Review per-post ping status.
- Remember that site-wide settings may not retroactively alter old posts.
- Understand that WordPress extracts URLs from post content.
- Understand that a post does not ping itself directly.
- Understand that another same-site post can remain a candidate.
- Remember that WordPress tracks previously pinged URLs.
- Understand the role of
_pingme. - Understand the role of
do_all_pingbacks(). - Understand the role of
pingback(). - Understand where
pre_pingruns. - Use
pre_pingfor targeted outgoing self-ping filtering. - Modify the target list by reference.
- Do not remove internal links merely to stop notifications.
- Use
home_url()carefully for local URL identification. - Consider HTTP vs HTTPS variants.
- Consider www vs non-www variants.
- Consider mapped domains.
- Consider multilingual domains.
- Consider Multisite.
- Consider subdirectory installations.
- Understand pingback endpoint discovery.
- Understand the role of
X-Pingback. - Understand the role of
rel="pingback". - Understand that pingbacks use XML-RPC communication.
- Do not assume
xmlrpc_enableddisables pingbacks. - Use
xmlrpc_methodsonly when method-level XML-RPC changes are required. - Keep incoming and outgoing policies separate.
- Keep self-pingbacks and external pingbacks separate.
- Keep comments and pingbacks separate.
- Keep pingbacks and trackbacks separate.
- Test with fresh source and destination posts.
- Use an absolute internal URL during controlled testing.
- Verify the destination accepts pings during diagnosis.
- Check timestamps on existing pingback records.
- Remember that disabling future self-pings does not delete historical ones.
- Back up before bulk cleanup.
- Do not describe self-ping filtering as complete XML-RPC hardening.
- Do not describe it as a major SEO feature.
- Do not describe it as a major performance optimization.
- Document the final discussion and XML-RPC configuration.
Related guides
- Disable Self-Pingbacks Without Disabling XML-RPC
- Pingbacks, Trackbacks & Internal Links
- XML-RPC in WordPress, Explained
- What Is XML-RPC in WordPress, and Why Disable It?
- WordPress Per-Post vs. Site-Wide Comment Settings
- How to Completely Disable Comments in WordPress
Final recommendation
The easiest way to understand WordPress self-pingbacks is to separate the hyperlink from the notification created around it.
The internal link is content:
Post A
→ Post B
The self-pingback is additional automated processing:
Post A
→ WordPress extracts URL
→ discovers pingback endpoint
→ sends pingback.ping
→ same site receives request
→ pingback may be stored on Post B
If that notification is useful to your editorial workflow, keep it.
If it is merely clutter, do not remove useful internal links and do not disable unrelated WordPress functionality just to stop it.
Use the narrowest appropriate control.
Need internal links
+
need external pingbacks
+
do not want self-pingbacks
→ use pre_ping
If you do not need any outgoing pingbacks:
disable outgoing ping notifications
more broadly
If you do not want incoming pingbacks:
review ping status
and XML-RPC pingback methods
If you do not need XML-RPC at all:
handle XML-RPC as
a separate compatibility
and security decision
TheOneWP Disable Self Pingbacks implements the focused approach. It hooks into WordPress’s native pre_ping stage, compares each outgoing URL with the current site home URL and removes matching same-site destinations before WordPress continues pingback processing.
The module does not edit the post, remove internal hyperlinks, disable external pingbacks, delete existing pingback records or disable XML-RPC.
The resulting model is simple:
internal linking
→ editorial decision
self-pingbacks
→ notification decision
external pingbacks
→ separate decision
XML-RPC
→ separate decision
comments
→ separate decision
Keeping those layers separate produces a WordPress configuration that is easier to understand, easier to troubleshoot and less likely to break functionality that has nothing to do with self-pingbacks.

