ActivityPub: {“error”:“Forbidden”,“code”:“SITE_MISSING”}

Trying to not hijack here – having related issues and attempting to pick best related thread rather than start a new one!

I also have a site migrated from CLI to docker. Updated to latest 6.0.3 and fresh docker pull. Separate admin domain (tried with and without).

The network tab has previously shown variations of all the other errors people are seeing, but is currently giving: ”Site not configured correctly: This feature can’t be used because the site isn’t set up correctly. If you manage this site, check your settings or server logs, or contact support”

The console shows all the .ghost/activitypub requests are returning 403 with

{“error”:“Forbidden”,“code”:“SITE_MISSING”}

On the docker logs site, I see a lot of (actual website removed):

activitypub-1          | 13:19:53.516 INF activitypub: 'GET' 'mywebsite.com' 'https://mywebsite.com/.ghost/activitypub/users/index' 'ddd37979-0f24-4c51-a1d6-a4e80eb8a1b7' 403 24ms
activitypub-1          | 13:19:53.520 INF activitypub: 'GET' 'mywebsite.com' 'https://mywebsite.com/.ghost/activitypub/v1/account/me' '8e667fb2-139c-42c9-8906-ddcaded1a18a'
activitypub-1          | 13:19:53.521 INF activitypub: KnexKvStore: Get key cachedJwks,mywebsite.com
activitypub-1          | 13:19:53.521 INF activitypub: No site found for 'mywebsite.com'

It seems like something is genuinely unconfigured, or failed at initial setup? Turning network setting off and on, or restarting ghost completely, don’t help, as I’ve seen in other threads.

Importantly, the domain is proxied on cloudflare, as is the admin - i have punched a hole in the proxy for .ghost/* but this hole wouldn’t have been there the first time it tried, so that may have caused it.

Is there a way to totally restart the setup process? Or something else that might be in the way here?

1 Like

Hey @ppittman , Did you edit the various environment files and caddyfile, as described in the upgrade directions? Sounds like you’re missing a step here.

I did.
In .env, I have ACTIVITYPUB_TARGET=activitypub:8080 uncommented and COMPOSE_PROFILES=analytics,activitypub (analytics works fine).

I’ve confirmed the docker activitypub container is running on 8080 as well:

cc21528d460f   ghcr.io/tryghost/activitypub:1.1.0   "docker-entrypoint.s…"   3 days ago       Up 3 days             8080/tcp    

In Caddyfile, both the regular domain and ADMIN_DOMAIN have import snippets/ActivityPub uncommented.

Is there anything else I’ve missed in there?

I’m assuming you’ve restarted Ghost since getting ActivityPub set up, yes? When Ghost starts, it should log something about activitypub being configured and having webhooks in the right state.

Yep:

ghost-1  | [2025-08-14 13:39:50] INFO Checking ActivityPub Webhook state
ghost-1  | [2025-08-14 13:39:50] INFO ActivityPub webhooks in correct state
ghost-1  | [2025-08-14 13:39:50] INFO Explore Response 200 OK
ghost-1  | [2025-08-14 13:39:53] INFO "GET /ghost/" 200 263ms

Moving this to its own topic. Less confusing that way. :slight_smile:

1 Like

@ppittman Did you get this sorted out? I’m in the same boat trying to use the self-hosted ActivityPub. I turned it on before I set up the proxy routes and now I can’t convince it to re-init.

One difference I’m seeing is this error from the Ghost container:
ERROR No webhook secret found - cannot initialise

I’ve confirmed the containers can talk to each other network-wise but I can’t get those same “No Site Found” errors and can’t seem to resolve it.

@JDiller nope still in the same boat. i even tried manually clearing out the activitypub database tables, and/or manually inserting a key in there. nothing helps! Hoping for a “let’s start this over” function in a release soon, I suppose. (Toggling it off and on does not achieve this)

Looked at the code and I got it working. Had a couple problems with my proxy config:

  1. Wasn’t forwarding the authorization header.

  2. Was rewriting the url needlessly.

I’m using nginx for my reverse proxy. Here’s what finally worked:
location ~ ^/.ghost/activitypub(?/.*)?$ {
proxy_pass ``http://127.0.0.1:8080``; # keep the /.ghost/activitypub prefix intact
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Authorization $http_authorization;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_no_cache 1;
proxy_cache_bypass 1;
}

Some of the calls between the Ghost and ActivityPub containers were failing I think due to the missing auth header. Forwarding $host is critical too too. It uses that to know what site it’s registering.

Nginx isn’t running inside the docker network but it is running on the same box, hence the 127.0.0.1. You’ll have to adjust that for your specific situation but if you’re using CloudFlare you probably know what to do there.

Once I had that in place and restarted Nginx, toggling “Network” off and on again did the trick.

1 Like

@JDiller It would be hard to overstate how grateful I am for your post!

I have spent a lot of time trying to get ActivityPub proxying working correctly with my slightly complex self-hosting setup. The backticks don’t work for me when using ap.ghost.org, and I left the location block as I had it, but adding the auth header (which I’d tried before, but at that point there must have been other issues) and the two cache settings finally did the trick.

Thank you!!