DIYgod/RSSHub · error

zhihu: failed to obtain a guest d_c0 cookie

Error message

zhihu: failed to obtain a guest d_c0 cookie

What it means

Thrown by the Zhihu anti-bot credential generator when it cannot obtain a guest `d_c0` cookie. The flow first requests `https://www.zhihu.com/explore` (with manual redirect handling) and scans the `Set-Cookie` headers for a `d_c0=` entry; if none is present, the whole `__zse_ck` challenge pipeline cannot proceed and this error is raised.

Source

Thrown at lib/routes/zhihu/utils.ts:113

    // `__zse_ck` is checked against the user-agent that generated it.
    const ua = generateHeaders()['user-agent'];
    const headers = { 'user-agent': ua };

    let dc0 = configuredDc0;
    if (!dc0) {
        const seed = await ofetch.raw('https://www.zhihu.com/explore', {
            headers,
            redirect: 'manual',
            ignoreResponseError: true,
        });
        dc0 =
            (seed.headers.getSetCookie?.() ?? [])
                .find((line) => line.startsWith('d_c0='))
                ?.split(';', 1)[0]
                .slice('d_c0='.length) || '';
    }
    if (!dc0) {
        throw new Error('zhihu: failed to obtain a guest d_c0 cookie');
    }

    const challenge = await ofetch.raw(`https://www.zhihu.com${apiPath}`, {
        headers: {
            ...headers,
            cookie: `d_c0=${dc0}; __zse_ck=005_x-x`,
            referer: url,
            'x-requested-with': 'fetch',
        },
        ignoreResponseError: true,
    });
    const html = challenge._data as string;
    const meta = html.match(/id="zh-zse-ck"[^>]*content="([^"]*)"/)?.[1];
    const hash = html.match(/zse-ck\/v4\/([a-f0-9]+)\.js/)?.[1];
    if (!meta || !hash) {
        throw new Error('zhihu: challenge page did not contain an URL to __zse_ck meta/script');
    }

View on GitHub (pinned to bed535e087)

Solutions

  1. Configure `config.zhihu.cookies` (env `ZHIHU_COOKIES`) with a real logged-in `d_c0` so the guest-seed step is skipped (`dc0 = configuredDc0`).
  2. Retry after a short interval — guest-cookie denial is often transient (rate limit / intermittent block).
  3. Run RSSHub from a residential/non-blocked IP or through a proxy that Zhihu does not flag.
  4. If `getSetCookie` is undefined in your Node/fetch version, upgrade Node (it needs `Headers.getSetCookie` support) or polyfill header parsing.

Example fix

# before — guest flow blocked, no d_c0
# (no ZHIHU_COOKIES set, /explore returns no d_c0)
# after — supply a d_c0 via config so the seed request is skipped
ZHIHU_COOKIES="d_c0=AAAA..."
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight: confirm /explore yields a d_c0 before depending on the guest flow
async function canGetGuestDc0() {
    const r = await ofetch.raw('https://www.zhihu.com/explore', { redirect: 'manual', ignoreResponseError: true });
    return (r.headers.getSetCookie?.() ?? []).some((l) => l.startsWith('d_c0='));
}

Try / catch

// Retry the guest-seed a few times; fall back to configured cookie
async function getDc0WithRetry(configuredDc0, attempts = 3) {
    if (configuredDc0) return configuredDc0;
    for (let i = 0; i < attempts; i++) {
        try {
            return await seedGuestDc0();
        } catch (e) {
            if (i === attempts - 1) throw e;
            await wait(1000 * (i + 1));
        }
    }
}

Prevention

When it happens

Trigger: Zhihu does not return a `d_c0` cookie on the `/explore` seed request — because the request was blocked, rate-limited, geo-restricted, or the response was an interstitial/captcha page rather than a normal one. A configured `config.zhihu.cookies` value bypasses this path entirely.

Common situations: RSSHub runs from an IP/datacenter Zhihu flags as suspicious; Zhihu tightens its bot detection and stops issuing guest cookies; a transient network error returns a non-HTML body; `getSetCookie` is unsupported by the runtime fetch layer so the cookie list looks empty.

Related errors


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