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

Thrown as ConfigNotFoundError by the Misskey home-timeline route (the second guard, after the token check). It fires when :site is not in utils.allowSiteList and config.feature.allow_user_supply_unsafe_domain is false — the same SSRF guard as the featured-notes route, but evaluated only after the access token is confirmed present.

Source

Thrown at lib/routes/misskey/home-timeline.ts:74

        },
    ],
    name: 'Home Timeline',
    maintainers: ['HanaokaYuzu'],
    handler,
    description: `::: warning
This route is only available for self-hosted instances.
:::`,
};

async function handler(ctx) {
    const access_token = config.misskey.accessToken;
    if (!access_token) {
        throw new ConfigNotFoundError('Missing access token for Misskey API. Please set `MISSKEY_ACCESS_TOKEN` environment variable.');
    }

    const site = ctx.req.param('site');
    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'.`);
    }

    // docs on: https://misskey.io/api-doc#tag/notes/operation/notes___timeline
    const url = `https://${site}/api/notes/timeline`;
    const routeParams = querystring.parse(ctx.req.param('routeParams'));
    const response = await got({
        method: 'post',
        url,
        headers: {
            Authorization: `Bearer ${access_token}`,
        },
        json: {
            limit: Number(routeParams.limit ?? 10),
            withFiles: queryToBoolean(routeParams.withFiles ?? false),
            withRenotes: queryToBoolean(routeParams.withRenotes ?? true),
            allowPartial: queryToBoolean(routeParams.allowPartial ?? true),
        },
    });

View on GitHub (pinned to bed535e087)

Solutions

  1. Set ALLOW_USER_SUPPLY_UNSAFE_DOMAIN=true (self-host only, understanding it affects all guarded routes) and restart RSSHub.
  2. Alternatively request an allow-listed instance, or add your instance to utils.allowSiteList if you control RSSHub.
  3. Confirm :site has no trailing slash/path (e.g. use 'misskey.example.com', not 'https://misskey.example.com/').
Defensive patterns

Strategy: validation

Validate before calling

const site = ctx.req.param('site');
if (!config.feature.allow_user_supply_unsafe_domain && !utils.allowSiteList.includes(site)) {
    throw new ConfigNotFoundError(`Host '${site}' not allowed. Enable ALLOW_USER_SUPPLY_UNSAFE_DOMAIN or use an allow-listed instance.`);
}

Type guard

function isAllowedSite(site: string, allowList: string[], unsafeAllowed: boolean): boolean {
    return typeof site === 'string' && (allowList.includes(site) || unsafeAllowed);
}

Prevention

When it happens

Trigger: A valid MISSKEY_ACCESS_TOKEN is set, but the requested :site is not on the curated allow-list and ALLOW_USER_SUPPLY_UNSAFE_DOMAIN is not enabled. The handler refuses to POST to an arbitrary host.

Common situations: Self-hoster correctly set the token for their own Misskey instance but their instance isn't in RSSHub's allow-list; they didn't know about the unsafe-domain toggle.

Related errors


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