majorwiki/02-selfhosting/services/mastodon-federation.md
majorlinux 91455fac39 Add 7 articles; update nav and existing articles (2026-04-25)
New articles:
- pihole-doh-dot-bypass-defense
- pihole-v6-adlist-management
- mastodon-db-maintenance
- mastodon-federation
- fantastical-google-phantom-calendar-syncselect
- rsync-tailscale-teardown-stall
- ollama-chat-template-pipe-stdin-bypass

Updated: wsl2-backup, wsl2-rebuild, ssh-config-key-management,
selfhosting index, mastodon-instance-tuning, ansible-check-mode,
windows-openssh, windows-sshd, yt-dlp, README, SUMMARY, index
Removed: fedora-usrmerge-ebtables-blocker (superseded by prior push)
2026-04-25 17:52:48 +00:00

5.8 KiB

title domain category tags status created updated
Mastodon Federation — Domain Blocks, Silencing, and FediSeer selfhosting services
mastodon
federation
fediverse
domain-blocks
fediseer
majortoot
published 2026-04-22 2026-04-22

Mastodon Federation — Domain Blocks, Silencing, and FediSeer

Domain Block Severity — Critical Gotcha

The Mastodon admin UI labels severities as Silence and Suspend, but the integer values stored in the database are not in alphabetical order. The Rails enum is:

# app/models/domain_block.rb
enum :severity, { silence: 0, suspend: 1, noop: 2 }, validate: true
DB value Meaning Effect
0 silence Instance limited — posts hidden from public timelines; follows require manual approval
1 suspend Full defederation — all content removed, all follows severed
2 noop No effect — entry tracked but no federation action taken

[!warning] Don't trust raw integer queries If you query domain_blocks directly via psql, severity 0 looks like "the lowest level" but it's actually silence — a meaningful restriction. Always map through the enum. This tripped up a defederation investigation on 2026-04-22 where 13 silenced instances (including mastodon.social) were initially misread as noop.

majortoot block inventory (as of 2026-04-22)

Severity Count Notable entries
silence (0) 13 mastodon.social, mastodon.world, chaos.social, fosstodon.org, tech.lgbt, threads.net
suspend (1) 413 Full defederation list
noop (2) 0

How Silencing Affects Follows

When your instance silences a remote domain, every follow request from that domain requires manual approval — even if your account has locked = false.

This is enforced in app/lib/activitypub/activity/follow.rb:

if target_account.locked? || @account.silenced?
  LocalNotificationWorker.perform_async(target_account.id, follow_request.id, 'FollowRequest', 'follow_request')

@account.silenced? returns true when the sending account's domain is in your domain_blocks at severity=0. The follow goes to the follow_requests queue instead of being automatically accepted.

Practical effect on majortoot: mastodon.social is silenced (added 2026-12-11, same day as a FluentInFinance follow-spam report). All follows from mastodon.social accounts appear as pending follow requests requiring manual approval. This is intentional — it's the expected behavior of a silence block.


Checking Defederation Status

Are major instances blocking you?

Check if your domain appears in another instance's public block list:

# Check mastodon.social's public block list (397 entries as of 2026-04-22)
curl -s "https://mastodon.social/api/v1/instance/domain_blocks" | \
  python3 -c "import sys,json; data=json.load(sys.stdin); \
  found=[b for b in data if b['domain']=='toot.majorshouse.com']; \
  print('BLOCKED' if found else 'Not in public block list')"

Note: instances can mark blocks as private, so absence from the public list is not a guarantee.

Are you in their peer list?

If you're in an instance's peer list, they've federated with you at some point:

curl -s "https://mastodon.social/api/v1/instance/peers" | \
  python3 -c "import sys,json; data=json.load(sys.stdin); print('toot.majorshouse.com' in data)"

Is the account visible from a remote instance?

curl -s "https://mastodon.social/api/v1/accounts/lookup?acct=majorlinux@toot.majorshouse.com" | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print('limited:', d.get('limited'), 'suspended:', d.get('suspended'))"

limited: true means the remote instance has silenced toot.majorshouse.com.

Check federation delivery health (Sidekiq)

ssh root@100.110.197.17 "redis-cli llen sidekiq:dead; redis-cli llen sidekiq:retry"
# Both should be 0 for a healthy instance

Check unavailable domains (delivery consistently failing)

ssh root@100.110.197.17 "
sudo -u postgres psql mastodon_production -c \
  'SELECT domain, updated_at FROM unavailable_domains ORDER BY updated_at DESC LIMIT 20;'"

These are domains where ActivityPub delivery has repeatedly failed. Most are dead instances, not active blocks.


FediSeer Registration

FediSeer is a community service that tracks censures (formal complaints) against fediverse instances. Registering lets you monitor if any instance formally censures toot.majorshouse.com.

majortoot status (registered 2026-04-22)

Field Value
Domain toot.majorshouse.com
ID 5575
State UP
Censures received 0
Endorsements 0
Tags mastodon, selfhosted, leftist, foss
Guarantor none
API key Bitwarden — "FediSeer — toot.majorshouse.com"

Claiming / re-claiming your instance

# Claim (sends API key via DM from @fediseer@fediseer.com)
curl -s -X PUT "https://fediseer.com/api/v1/whitelist/toot.majorshouse.com" \
  -H "Content-Type: application/json" \
  -d '{"admin": "majorlinux", "pm_proxy": "MASTODON"}'

# The API key arrives as a DM — delete the DM after saving to Bitwarden

Check censures

curl -s "https://fediseer.com/api/v1/censures/toot.majorshouse.com" | python3 -c \
  "import sys,json; d=json.load(sys.stdin); print('Censures:', d.get('total',0))"

Update tags

curl -s -X PUT "https://fediseer.com/api/v1/tags" \
  -H "Content-Type: application/json" \
  -H "apikey: <key-from-bitwarden>" \
  -d '{"tags_csv": "mastodon,selfhosted,leftist,foss"}'

See Also