DIYgod/RSSHub · error · RejectError
Authentication failed. Access denied.\n${requestPath}
Error message
Authentication failed. Access denied.\n${requestPath} What it means
Thrown by the access-control middleware when an operator has set ACCESS_KEY and the incoming request fails both auth checks. A request is allowed only if query param `key` exactly equals config.accessKey, or query param `code` equals md5(requestPath + accessKey). Paths '/', '/robots.txt', '/favicon.ico', '/logo.png' are exempt. It uses RejectError, which RSSHub maps to a distinct rejection response (HTTP 403) rather than a generic 500.
Source
Thrown at lib/middleware/access-control.ts:8
import type { MiddlewareHandler } from 'hono';
import { config } from '@/config';
import RejectError from '@/errors/types/reject';
import md5 from '@/utils/md5';
const reject = (requestPath) => {
throw new RejectError(`Authentication failed. Access denied.\n${requestPath}`);
};
const middleware: MiddlewareHandler = async (ctx, next) => {
const requestPath = new URL(ctx.req.url).pathname;
const accessKey = ctx.req.query('key');
const accessCode = ctx.req.query('code');
if (['/', '/robots.txt', '/favicon.ico', '/logo.png'].includes(requestPath)) {
await next();
} else {
if (config.accessKey && !(config.accessKey === accessKey || accessCode === md5(requestPath + config.accessKey))) {
return reject(requestPath);
}
await next();
}
};
export default middleware;View on GitHub (pinned to bed535e087)
Solutions
- Append `?key=<your ACCESS_KEY value>` to the RSSHub URL.
- Or compute `?code=md5(pathname + ACCESS_KEY)` (lowercase hex) and append it.
- If protection is unwanted, unset the ACCESS_KEY env var and restart the instance.
- Ensure no reverse proxy/CDN strips query parameters before the request reaches RSSHub.
Example fix
// before
https://rsshub.example.com/bbc
// after (share-the-key form)
https://rsshub.example.com/bbc?key=YOUR_ACCESS_KEY
// after (code form: md5('/bbc' + ACCESS_KEY))
https://rsshub.example.com/bbc?code=<md5hex> Defensive patterns
Strategy: validation
Validate before calling
// Client side: compute the access code before the call.
import crypto from 'node:crypto';
const ACCESS_KEY = process.env.ACCESS_KEY!;
const pathname = new URL(targetUrl).pathname;
const code = crypto.createHash('md5').update(pathname + ACCESS_KEY).digest('hex');
const authedUrl = new URL(targetUrl);
if (!authedUrl.searchParams.has('key') && !authedUrl.searchParams.has('code')) {
authedUrl.searchParams.set('code', code);
} Type guard
// Narrow an authenticated request before sending.
const isAuthed = (u: URL, accessKey: string): boolean =>
u.searchParams.get('key') === accessKey ||
u.searchParams.get('code') ===
crypto.createHash('md5').update(u.pathname + accessKey).digest('hex'); Try / catch
// Operators usually do not catch this — it is a deliberate 403.
// If automating, treat a 403 from access-control as a credentials issue, not a retry candidate.
if (res.status === 403 && /Access denied/.test(body)) {
throw new Error('RSSHub access key missing/wrong — fix credentials, do not retry');
} Prevention
- Document the ACCESS_KEY and the md5(path+key) code scheme to all feed consumers.
- Ensure reverse proxies preserve the query string.
- Use the same ACCESS_KEY value across all clients; rotate by updating everyone in lockstep.
When it happens
Trigger: config.accessKey is set (e.g. ACCESS_KEY env) and the request to any non-exempt path omits both `?key=` and `?code=`, supplies a wrong key, or supplies a code computed against a different path/accessKey.
Common situations: Operator enables ACCESS_KEY to protect a public instance but forgets to distribute the key; client uses `?code=` computed with a stale or URL-encoded path; reverse proxy strips the query string; CI hits a protected route without credentials.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid URL property: ${prop}
- Invalid Engine Value: ${engine}, please check your config.
- Login required
- Disqus RSS is disabled due to the lack of <a href="https://d
- Fanfou RSS is disabled due to the lack of <a href="https://d
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/d4cd898eb5452ada.
Report an issue: GitHub.