DIYgod/RSSHub · warning · ConfigNotFoundError

This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN

Error message

This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.

What it means

ConfigNotFoundError thrown by the Mastodon hashtag timeline route when :site is not allowlisted and ALLOW_USER_SUPPLY_UNSAFE_DOMAIN is false. Same SSRF guard pattern as the other Mastodon site-param routes; the hashtag is then fetched from http://<site>/api/v1/timelines/tag/<hashtag>.

Source

Thrown at lib/routes/mastodon/tag.ts:37

        only_media: {
            description: 'whether only display media content, default to false, any value to true',
            options: [
                { value: 'true', label: 'true' },
                { value: 'false', label: 'false' },
            ],
            default: 'false',
        },
    },
    name: 'Hashtag timeline',
    maintainers: ['yuikisaito'],
    handler,
};

async function handler(ctx: Context): Promise<Data> {
    const { site, hashtag } = ctx.req.param();
    const only_media = ctx.req.param('only_media') === 'true' ? 'true' : 'false';
    if (!config.feature.allow_user_supply_unsafe_domain && !utils.allowSiteList.includes(site)) {
        throw new ConfigNotFoundError(`This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
    }

    const url = `http://${site}/api/v1/timelines/tag/${hashtag}?only_media=${only_media}`;

    const response = await got.get(url, { headers: utils.apiHeaders(site) });
    const list = response.data;

    return {
        title: `#${hashtag} ${only_media === 'true' ? ' Media' : ''} Timeline on ${site}`,
        link: `https://${site}`,
        item: utils.parseStatuses(list),
    };
}

View on GitHub (pinned to bed535e087)

Solutions

  1. Set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true for a private/trusted deployment.
  2. Set MASTODON_API_HOST to your instance to add it to the allowlist.
  3. Verify the site segment has no protocol or path (just the host, e.g. 'fosstodon.org').
  4. On public instances, keep the guard on and request an allowlist addition instead.
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED = ['mastodon.social','pawoo.net','fosstodon.org', config.mastodon.apiHost].filter(Boolean);
if (!ALLOWED.includes(site) && !config.feature.allow_user_supply_unsafe_domain) {
    throw new ConfigNotFoundError('Instance not allowlisted; set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true or MASTODON_API_HOST');
}

Type guard

const isAllowlistedSite = (site: string): boolean =>
    ['mastodon.social','pawoo.net','fosstodon.org', config.mastodon.apiHost].filter(Boolean).includes(site);

Prevention

When it happens

Trigger: GET /mastodon/tag/:site/:hashtag where :site is not mastodon.social/pawoo.net/fosstodon.org/MASTODON_API_HOST and the unsafe-domain feature flag is off.

Common situations: Following a hashtag on a non-allowlisted instance; public RSSHub deployment with the guard intentionally on; typo in the site segment of the route.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/58f2f72c86dca7c3. Report an issue: GitHub.