Blog / Privacy

  • activitypub
  • fediverse
  • mastodon
  • privacy
  • uk-gdpr
  • federation

Why a Federated Server Can't Delete Your Post from Everyone Else's

When you delete a post on a Mastodon-style server, your server does not delete it everywhere. It sends a message to other servers saying "please forget this", and each one decides what to do. Most comply. None have to, and nothing can check.

That is not a bug in one piece of software. It falls out of how federation works, and it is worth understanding before you decide what you are willing to post.

What a delete actually is on the wire

In ActivityPub, a post is an object with a URL, and deleting it means sending a Delete activity to the inboxes of the servers that might hold a copy. Mastodon typically sends a Tombstone as the object, which is a stub saying "something used to live at this URL".

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://example.social/users/andy/statuses/123#delete",
  "type": "Delete",
  "actor": "https://example.social/users/andy",
  "to": ["https://www.w3.org/ns/activitystreams#Public"],
  "object": {
    "id": "https://example.social/users/andy/statuses/123",
    "type": "Tombstone"
  }
}

This is an HTTP POST, signed so the receiver can check it came from your server. The receiver verifies the signature, checks that the actor owns the object, and (if it is well behaved) removes its stored copy.

The key word is "if". The ActivityPub specification describes what a Delete means. It does not give you a way to force another operator's database to change.

Where the copies live

A post you publish ends up in more places than the follower list suggests. Roughly:

  • the home servers of everyone who follows you, who each store their own copy
  • servers that saw it through a boost, a reply thread or a relay
  • media caches, which often outlive the post that referenced them
  • search indexers, archives and scrapers that never spoke ActivityPub at all
  • screenshots, quotes and replies written by other people

Only the first few can even receive your Delete. A scraper has no inbox. A screenshot has no URL. Your server cannot address them, so it cannot ask.

Quick detour: why servers are told at all

Hang on, why do other servers keep copies in the first place? Because fetching a remote post every time someone scrolls would be slow and would hammer the origin. Federation works by pushing a copy to each recipient once, then serving it locally.

That is the same design choice that makes delivery cheap, and it is the one that makes deletion advisory. A copy that is pushed has to be pulled back, and pulling needs the recipient's cooperation.

Ways a delete quietly fails

Even between two honest servers, deletes go missing. The usual causes:

  1. The receiving server was down. Senders retry with backoff, but retries are finite, so a long outage can outlast them.
  2. The receiver does not know who was holding a copy. Your server only delivers to places it remembers delivering to, and a copy that arrived via a boost may sit somewhere else.
  3. The receiver rejects the activity. Signature checks, a changed key or a bad actor URL all give a polite refusal and no deletion.
  4. The receiver is not running Mastodon, and handles Delete differently, or not at all.
  5. The receiver is simply hostile or indifferent. Nothing stops an operator ignoring the message.

A delete is only as reliable as the least careful server that received the post. That is the whole threat model in one sentence.

Deleting your whole account is the awkward case

Account deletion sends a Delete for the actor itself, and receivers are meant to drop everything from that account. The catch is that verifying the signature needs your public key, and your server may now answer with "gone" when asked for it.

Implementations have had to special-case this: an actor deletion from an actor that no longer resolves is usually treated as safe to act on, because the alternative is a graveyard of cached accounts. Whether a given server does so depends on its software and version.

What UK GDPR says about it

The legal position is different from the technical one, and the two are easy to blur. Article 17 of UK GDPR gives a right to erasure in certain circumstances. Article 17(2) adds that where a controller has made personal data public and must erase it, it must take "reasonable steps", taking account of available technology and the cost, to tell other controllers who are processing it.

Note what that is: a duty to take reasonable steps and inform, not a guarantee of erasure. Sending a Delete to known recipients looks like exactly that kind of step. That is my reading, though, not a court ruling, and it depends on who the controller actually is. A small instance run as a hobby may have a household-purposes argument that a larger one will not.

Each receiving operator is a separate controller of their own copy. The ICO's guidance on erasure is the place to check how that applies to a particular case. I have not seen a decision that settles how this works for federated servers specifically.

What to do with this

Treat a public federated post the way you would treat anything you have emailed to a few thousand people. Most will honour a request to bin it. You cannot prove they all did.

  • Post things you would be fine seeing again later.
  • Use followers-only or direct visibility for anything sensitive, remembering that a follower's server still keeps a copy.
  • If you run an instance, process incoming Delete activities promptly and purge cached media too, not just the text.
  • If something genuinely harmful has spread, contact the admins of the big instances directly. A human message often works better than the protocol.

The odd upside is that the system is honest about its limits once you know where to look. The delete button is a request, and it is a decent one.