ActivityPub Initialization Error on Self-Hosted Ghost – "No webhook secret found"

I’m running into an issue with the ActivityPub feature on my self-hosted Ghost installation and could use some advice from anyone who’s encountered something similar.

Previously, I had a Ghost server where I enabled ActivityPub, which registered the username @index@craftedsilicon.com with ap.ghost.org. I later deleted that server completely.

Now, with a new Ghost instance on a different server using the same domain, enabling ActivityPub fails with: “ERROR No webhook secret found - cannot initialise”.

It looks like the old account for @index@craftedsilicon.com is still lingering in the system, blocking the new setup. I’m self-hosting via CLI, the ActivityPub service is running per docs, and I have full DNS access to craftedsilicon.com.

Has anyone dealt with this when reusing a domain for ActivityPub? Specifically:

  • Ways to reset or retrieve the webhook secret for an existing account?

  • How to re-register the username after deleting an old server?

  • Any workarounds to clear the old data?

Insights or experiences welcome—thanks!

4 Likes

I am also facing the same error and haven’t found a direct solution.

I have found two workarounds, but they may not be very practical in your case or mine:

  • Switch to a Docker installation and self-host the ActivityPub Service
  • Change the domain (adding a subdomain is also acceptable)
1 Like

Thanks @Kentone . However, I’m concerned that switching to a self-hosted ActivityPub setup might result in two instances appearing in the Fediverse. Specifically, when searching from Mastodon, it might only show one profile with the same username, and that might not be the new self-hosted one, causing confusion. While using a subdomain seems like a viable workaround, adding a subdomain to an already large domain feels impractical in my case. I’ve raised this issue with the Ghost team by emailing support@ghost.org, and I’m hoping for some clarity. Thanks again for your input—I’ll keep you posted on what I hear back!

1 Like

This would not happy :slight_smile:

ActivityPub works via DNS. Essentially, Mastodon (or any other AP instance) would query your domain, which then returns the AP data.

Right now, Ghost is connecting to ap.ghost.org to fetch that information. If you self-host AP your self, Ghost would query the local container. For Mastodon it essentially looks the same (some nuances, but broadly speaking yes).

Thanks for clarifying that, @jannis —makes sense that self-hosting the ActivityPub service would keep everything resolved via DNS without creating duplicates, since Mastodon would just query my domain and get routed to the local setup.

One thing I’m still unclear on: if there’s currently no active ActivityPub connected to my DNS (old server fully deleted, new one not enabled due to the error), why does the profile for @index@craftedsilicon.com still show up when I search for it on Mastodon? And not just the profile itself, but even the description is showing the old one from the previous setup. Is that due to some kind of caching in the Fediverse, or is the old data lingering on ap.ghost.org in a way that allows resolution even without my domain responding properly?

Not necessarily on the Fediverse (since there’s not a single entity for that), but on that particluar Mastodon instance, yes.

I usually use https://browser.pub to debug any ActivityPub-related things. That always fetches things from the actual domain and shows what’s going on there.

Thanks @jannis for the clarification. I’ve checked https://browser.pub and confirmed that I’m redirecting https://craftedsilicon.com/.ghost/activitypub/users/index to ap.ghost.org. However, it seems the data on ap.ghost.org is tied to an outdated Ghost installation. To resolve this, I could either contact the Ghost team to request deletion of the current public key, allowing a new instance to initialize, or consider using a different subdomain. As a last resort, setting up my own ActivityPub server might be an option. Let me know if you have any further insights or recommendations!

If anyone from ghost team is seeing this please help with the deletion, I already send out a mail to support@ghost.org last Thursday, still no response.

Update on this issue @Kentone and @jannis, No Response from support@ghost.org on the same. I have sent out one more and still nothing. The automation mail said they will get back from monday to friday, but its been 10 days now.

Ghost Team, Please provide a solution for the same.

2 Likes

So… maybe it’s a problem with your previous setup. But OTOH, maybe it isn’t. Ghost logs that error on startup any time ActivityPub isn’t initialized.

Are there any additional messages in the Ghost logs on start up? Are there any 404s in the Ghost logs on startup? Are there any errors or non-2xx errors in your nginx (or whatever is proxying) when you first start Ghost?

I’m looking for some indication of requests not getting to the right place, whether from your Ghost instance or inbound from ap.ghost.org as it validates your site.

1 Like

Hi @Cathy_Sarisky, thank you for taking a look at the issue.

Please check out the following ghost restart logs:

ubuntu@ghost-247202:/var/www/ghost$ ls
config.production.json  content  current  system  versions
ubuntu@ghost-247202:/var/www/ghost$ ghost restart && ghost log -f

Love open source? We’re hiring JavaScript Engineers to work on Ghost full-time.
https://careers.ghost.org


+ sudo systemctl is-active ghost_craftedsilicon-com
+ sudo systemctl restart ghost_craftedsilicon-com
✔ Restarting Ghost

Love open source? We’re hiring JavaScript Engineers to work on Ghost full-time.
https://careers.ghost.org


+ sudo systemctl is-active ghost_craftedsilicon-com
[2025-09-21 16:40:41] INFO Database is in a ready state.
[2025-09-21 16:40:41] INFO Ghost database ready in 0.746s
[2025-09-21 16:40:41] WARN Missing mail.from config, falling back to a generated email address. Please update your config file and set a valid from address
[2025-09-21 16:40:42] INFO Invalidating assets for regeneration
[2025-09-21 16:40:42] INFO Adding offloaded job to the inline job queue
[2025-09-21 16:40:42] INFO Scheduling job mentions-email-report at 33 17 * * * *. Next run on: Sun Sep 21 2025 17:17:33 GMT+0000 (Coordinated Universal Time)
[2025-09-21 16:40:43] INFO Pinging Explore with Payload https://explore.ghost.org/api/update {"ghost":"6.0.9","site_uuid":"df35b572-53b3-4bac-9e34-48ed3a0aaf9d","url":"https://craftedsilicon.com","theme":"headline","facebook":"craftedsilicon","twitter":"@craftedsilicon","posts_total":35,"posts_last":"2025-09-18T02:38:45.000Z","posts_first":"2025-05-12T15:31:23.000Z"}
[2025-09-21 16:40:43] INFO Adding offloaded job to the inline job queue
[2025-09-21 16:40:43] INFO Scheduling job clean-expired-comped at 51 40 0 * * *. Next run on: Mon Sep 22 2025 00:40:51 GMT+0000 (Coordinated Universal Time)
[2025-09-21 16:40:43] INFO Adding offloaded job to the inline job queue
[2025-09-21 16:40:43] INFO Scheduling job clean-tokens at 25 19 2 * * *. Next run on: Mon Sep 22 2025 02:19:25 GMT+0000 (Coordinated Universal Time)
[2025-09-21 16:40:43] INFO Ghost booted in 2.979s
[2025-09-21 16:40:43] INFO Adding offloaded job to the inline job queue
[2025-09-21 16:40:43] INFO Scheduling job email-analytics-fetch-latest at 19 1/5 * * * *. Next run on: Sun Sep 21 2025 16:41:19 GMT+0000 (Coordinated Universal Time)
[2025-09-21 16:40:43] INFO Adding offloaded job to the inline job queue
[2025-09-21 16:40:43] INFO Scheduling job update-check at 18 43 12 * * *. Next run on: Mon Sep 22 2025 12:43:18 GMT+0000 (Coordinated Universal Time)
[2025-09-21 16:40:43] INFO Running milestone emails job on Sun Sep 21 2025 16:40:43 GMT+0000 (Coordinated Universal Time)
[2025-09-21 16:40:43] INFO Bootstrap client was closed.
[2025-09-21 16:40:43] INFO URL Service ready in 1809ms
[2025-09-21 16:40:44] INFO Explore Response 200 OK
[2025-09-21 16:40:45] ERROR No webhook secret found - cannot initialise
[2025-09-21 16:41:05] INFO "GET /favicon.ico" 200 86ms
[2025-09-21 16:41:05] INFO "GET /" 200 1560ms
[2025-09-21 16:41:05] INFO "GET /assets/built/screen.css?v=bcbf86dc8c" 200 10ms
[2025-09-21 16:41:05] INFO "GET /public/cards.min.css?v=bcbf86dc8c" 200 16ms
[2025-09-21 16:41:06] INFO "GET /assets/built/main.min.js?v=bcbf86dc8c" 200 9ms
[2025-09-21 16:41:06] INFO "GET /public/cards.min.js?v=bcbf86dc8c" 200 11ms
[2025-09-21 16:41:06] INFO "GET /public/comment-counts.min.js?v=bcbf86dc8c" 200 13ms
[2025-09-21 16:41:06] INFO "GET /public/member-attribution.min.js?v=bcbf86dc8c" 200 14ms
[2025-09-21 16:41:06] INFO "GET /members/api/member/" 204 23ms
[2025-09-21 16:41:06] INFO "GET /members/api/comments/counts/?ids=68cb6ee620f66d40acc13908,68ca1ada20f66d40acc138f9,68c6da336182a092c021c814,68c64be26182a092c021c7f8,68c552d96182a092c021c7e5,68c329ce6182a092c021c7bc,68c311fe6182a092c021c7af,68bedb7ddc7275f895f7e8d3,68bc4e089651d2a847ba9bfe,68b9898fbc4e7b6fae45f19f,68b900e9bc4e7b6fae45f193" 304 34ms
[2025-09-21 16:41:06] INFO "GET /ghost/api/content/settings/?key=eb478300e43498a95a65c3bb20" 304 122ms
[2025-09-21 16:41:06] INFO "GET /ghost/api/content/tiers/?limit=100&include=monthly_price%2Cyearly_price%2Cbenefits&key=eb478300e43498a95a65c3bb20" 304 23ms
[2025-09-21 16:41:06] INFO "GET /ghost/api/content/newsletters/?limit=100&key=eb478300e43498a95a65c3bb20" 304 28ms
[2025-09-21 16:41:06] INFO "GET /favicon.ico" 200 26ms
[2025-09-21 16:41:19] INFO Worker for job "email-analytics-fetch-latest" online
[2025-09-21 16:41:19] INFO [EmailAnalytics] Fetch latest opened events started
[2025-09-21 16:41:19] INFO Worker for job email-analytics-fetch-latest sent a message: done
[2025-09-21 16:41:19] INFO [EmailAnalytics] Fetching from 2025-09-06T15:30:13.000Z until 2025-09-21T16:40:19.477Z (maxEvents: 10000)
[2025-09-21 16:41:20] ERROR
[2025-09-21 16:41:20] ERROR [EmailAnalytics] Error while fetching
[2025-09-21 16:41:20] ERROR
[2025-09-21 16:41:20] INFO [EmailAnalytics] No new events found
[2025-09-21 16:41:20] ERROR
[2025-09-21 16:41:20] ERROR

I don’t see any other error logs that are really related to ActivityPub.

Just this one:

[2025-09-21 16:40:45] ERROR No webhook secret found - cannot initialise

For some additional context, the following is browser.pub json for the handle @index@craftedsilicon.com:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://w3id.org/security/v1",
    "https://w3id.org/security/data-integrity/v1",
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/multikey/v1",
    {
      "alsoKnownAs": {
        "@id": "as:alsoKnownAs",
        "@type": "@id"
      },
      "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
      "movedTo": {
        "@id": "as:movedTo",
        "@type": "@id"
      },
      "toot": "http://joinmastodon.org/ns#",
      "Emoji": "toot:Emoji",
      "featured": {
        "@id": "toot:featured",
        "@type": "@id"
      },
      "featuredTags": {
        "@id": "toot:featuredTags",
        "@type": "@id"
      },
      "discoverable": "toot:discoverable",
      "suspended": "toot:suspended",
      "memorial": "toot:memorial",
      "indexable": "toot:indexable",
      "schema": "http://schema.org#",
      "PropertyValue": "schema:PropertyValue",
      "value": "schema:value",
      "misskey": "https://misskey-hub.net/ns#",
      "_misskey_followedMessage": "misskey:_misskey_followedMessage",
      "isCat": "misskey:isCat"
    }
  ],
  "id": "https://craftedsilicon.com/.ghost/activitypub/users/index",
  "type": "Person",
  "inbox": "https://craftedsilicon.com/.ghost/activitypub/inbox/index",
  "publicKey": {
    "id": "https://craftedsilicon.com/.ghost/activitypub/users/index#main-key",
    "type": "CryptographicKey",
    "owner": "https://craftedsilicon.com/.ghost/activitypub/users/index",
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsRV+wava8SXGvWGRc2CQ\nLH3ypzmfD0bOHTyFKhDtpn7I5RNYRioeMDG2nZPVzzhgtZyBmprCLNlHJw2RSDms\nJiVkVpOekXIlsbqZiOD/HKLFIRB1f8Ovnqx7QUpA8cWqwfJEMPGOfR9RMYlrlPEa\nQ5LjUOT0HZEPxFma9pLGPugAZC1EvjK8/6jFl+uHltB+kvG+XMvo3ebnRxyQ7iEX\nzCeNA7JqxFEcYaJTL3uqRHbug5CWNewne0sGWE52JU/G4IeHYk4k2iK3ZvUbY/w3\niwM1K6CY9lC4Iu1sKcmkwBbH2KSiKLjE+9Re2zvdCpuQaDdFRA6RPQ4u8UXc/S5X\n0YGALUp5cOGlXVmNL4wRejtQhS0lwXqnuKEJCntxNxxag+lew8LwdT9nMeNo06Ms\n8jdwPV0nBMoFEUePFXi/dk02eU6fNnI9vUVM/BW9OEqjKz5zJpWh9z7SRn17pPrx\nnWVY5b9jurybqvOQ2hoLVcxN6mCc2+D32lmFM8nvrHd2OHK7IPvOuYeafIX5E50G\nasKsu2dgQiKvq9YP/kb/oZqAVvp3wpec41ucXfCj+e/K7auTioS1J/P24yuIFIkB\nK0ZRqCIhS37VqH1GVQnjnKE1LO/VLvLLCYS0vzK+FtF6h3AeLtRAH52Yb+augZoj\n5nIV/IV6ct95U61pLZj8SCkCAwEAAQ==\n-----END PUBLIC KEY-----\n"
  },
  "followers": "https://craftedsilicon.com/.ghost/activitypub/followers/index",
  "following": "https://craftedsilicon.com/.ghost/activitypub/following/index",
  "image": {
    "type": "Image",
    "url": "https://static.ghost.org/v5.0.0/images/publication-cover.jpg"
  },
  "liked": "https://craftedsilicon.com/.ghost/activitypub/liked/index",
  "name": "Daily Dev Tips",
  "outbox": "https://craftedsilicon.com/.ghost/activitypub/outbox/index",
  "preferredUsername": "index",
  "summary": "Tech and Dev Tips and Tricks",
  "url": "https://craftedsilicon.com/"
}

I appreciate any input that you can provide.

Any errors at the same time over in the Caddy container?

Hey @aswinsam,

Thanks for your patience! The Ghost core team was away last week for our annual team week, so replies have been slower than usual. Sorry about that!

There was indeed an outdated entry for the domain craftedsilicon.com in the ActivityPub database behind ap.ghost.org, that I’ve now cleared. Restarting your Ghost container with docker compose restart should normally now fix the initialisation issue! If not, Ghost logs will be useful to debug further :slight_smile:

3 Likes

Hi @Sag, thank you for your assistance. Now, I can see that the ap.ghost.org connectivity to craftedsilicon is gone, as mentioned. Which I can see in https://browser.pub/, when I now search for @indexindex@craftedsilicon.com, it says:

Submitting input form: @index@craftedsilicon.com
Trying: @index@craftedsilicon.com
403 in 1916ms
access-control-allow-credentials: true
access-control-allow-origin: *
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
cache-control: public, max-age=0
cf-cache-status: DYNAMIC
cf-ray: 9832e17897f10548-SIN
connection: keep-alive
content-length: 43
content-type: application/json
date: Mon, 22 Sep 2025 15:36:58 GMT
server: cloudflare
surrogate-control: max-age=60, stale-while-revalidate=300, stale-if-error=0
vary: Origin
via: 1.1 google
x-cloud-trace-context: a9a8aeb22daa96d50b32a0af8ed700bd
{
  "error": "Forbidden",
  "code": "SITE_MISSING"
}
{"kind":"not-found","reason":"Error: Unexpected webfinger status: 403"}

So, I guess everything is clear from ap.ghost.org’s side; however, I am still getting this error after ghost restart:

ubuntu@ghost-247202:/var/www/ghost$ ghost restart && ghost log -f

Love open source? We’re hiring JavaScript Engineers to work on Ghost full-time.
https://careers.ghost.org


+ sudo systemctl is-active ghost_craftedsilicon-com
+ sudo systemctl restart ghost_craftedsilicon-com
✔ Restarting Ghost

Love open source? We’re hiring JavaScript Engineers to work on Ghost full-time.
https://careers.ghost.org


+ sudo systemctl is-active ghost_craftedsilicon-com
[2025-09-22 15:40:03] INFO Bootstrap client was closed.
[2025-09-22 15:40:03] INFO Database is in a ready state.
[2025-09-22 15:40:03] INFO Ghost database ready in 0.667s
[2025-09-22 15:40:03] WARN Missing mail.from config, falling back to a generated email address. Please update your config file and set a valid from address
[2025-09-22 15:40:04] INFO Invalidating assets for regeneration
[2025-09-22 15:40:04] INFO Adding offloaded job to the inline job queue
[2025-09-22 15:40:04] INFO Scheduling job mentions-email-report at 10 13 * * * *. Next run on: Mon Sep 22 2025 16:13:10 GMT+0000 (Coordinated Universal Time)
[2025-09-22 15:40:05] INFO Pinging Explore with Payload https://explore.ghost.org/api/update {"ghost":"6.0.9","site_uuid":"df35b572-53b3-4bac-9e34-48ed3a0aaf9d","url":"https://craftedsilicon.com","theme":"headline","facebook":"craftedsilicon","twitter":"@craftedsilicon","posts_total":35,"posts_last":"2025-09-18T02:38:45.000Z","posts_first":"2025-05-12T15:31:23.000Z"}
[2025-09-22 15:40:05] INFO Adding offloaded job to the inline job queue
[2025-09-22 15:40:05] INFO Scheduling job clean-expired-comped at 39 2 0 * * *. Next run on: Tue Sep 23 2025 00:02:39 GMT+0000 (Coordinated Universal Time)
[2025-09-22 15:40:05] INFO Adding offloaded job to the inline job queue
[2025-09-22 15:40:05] INFO Scheduling job clean-tokens at 40 36 4 * * *. Next run on: Tue Sep 23 2025 04:36:40 GMT+0000 (Coordinated Universal Time)
[2025-09-22 15:40:05] INFO Ghost booted in 2.69s
[2025-09-22 15:40:05] INFO Adding offloaded job to the inline job queue
[2025-09-22 15:40:05] INFO Scheduling job email-analytics-fetch-latest at 31 4/5 * * * *. Next run on: Mon Sep 22 2025 15:44:31 GMT+0000 (Coordinated Universal Time)
[2025-09-22 15:40:05] INFO Adding offloaded job to the inline job queue
[2025-09-22 15:40:05] INFO Scheduling job update-check at 40 40 14 * * *. Next run on: Tue Sep 23 2025 14:40:40 GMT+0000 (Coordinated Universal Time)
[2025-09-22 15:40:05] INFO Running milestone emails job on Wed Sep 24 2025 15:40:05 GMT+0000 (Coordinated Universal Time)
[2025-09-22 15:40:05] INFO Bootstrap client was closed.
[2025-09-22 15:40:05] INFO URL Service ready in 1600ms
[2025-09-22 15:40:06] INFO Explore Response 200 OK
[2025-09-22 15:40:07] ERROR No webhook secret found - cannot initialise
[2025-09-22 15:40:07] INFO "GET /rss/" 200 1450ms

Note: I am using Ghost CLI Deployment, Not Docker. Hence, I did Ghost Restart (I also tried ghost stop and then ghost start)

Now, I can confirm that https://craftedsilicon.com/.ghost/activitypub/v1/account/me now gives:

{"error":"Forbidden","code":"SITE_MISSING"}

Before it was ROLE_MISSING

My Domain is on Cloudflare.

The following is my craftedsilicon.com-ssl.conf:

ubuntu@ghost-247202:/var/www/ghost$ cat /etc/nginx/sites-available/craftedsilicon.com-ssl.conf 
map $status $header_content_type_options {
    204 "";
    default "nosniff";
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name craftedsilicon.com;
    root /var/www/ghost/system/nginx-root; # Used for acme.sh SSL verification (https://acme.sh)

    ssl_certificate /etc/letsencrypt/craftedsilicon.com/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/craftedsilicon.com/craftedsilicon.com.key;
    include /etc/nginx/snippets/ssl-params.conf;

    location ~ /.ghost/activitypub/* {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        add_header X-Content-Type-Options $header_content_type_options;
        proxy_ssl_server_name on;
        proxy_pass https://ap.ghost.org;
    }

    location ~ /.well-known/(webfinger|nodeinfo) {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        add_header X-Content-Type-Options $header_content_type_options;
        proxy_ssl_server_name on;
        proxy_pass https://ap.ghost.org;
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
        
        add_header X-Content-Type-Options $header_content_type_options;
    }

    client_max_body_size 1g;
}

I know it is an issue from my side now and not with ap.ghost.org, but do let me know if you have any inputs on the same.

1 Like

@aswinsam Interesting: I have the exact same errors, with a similar set-up:

I’m getting webhook not initialized error in the logs, 403 errors for ActivityPub requests (SITE_MISSING), and 403 unexpected webfinger status from BrowserPub. (I, also, suspect there might be a bad entry for my site in the ap.ghost.org database because I did a lot of tinkering trying to get ActivityPub working, from multiple different domains, before I knew what I was doing.)

1 Like

@aswinsam would you be able to restart your Ghost container again? I believe there was another outdated cached entry that I missed yesterday.

2 Likes

Awesome @Sag , Everything is working now. Thank you very much for the support.

Special Thanks to @Cathy_Sarisky, @jannis, @Kentone and @curiositry for your help as well in debugging this issue.

3 Likes