decolua/9router · error
Missing API key
Error message
Missing API key
What it means
API-key enforcement is enabled in the gateway settings (requireApiKey=true) but no API key was found on the request. extractApiKey(request) looks at the Authorization header (Bearer token) and possibly x-api-key; when it returns nothing and enforcement is on, the handler returns 401 with 'Missing API key'.
Source
Thrown at src/sse/handlers/chat.js:68
const modelStr = body.model;
// Request summary is emitted as the unified "▶" line in chatCore (has fmt/thinking/account)
// Log API key (masked)
const authHeader = request.headers.get("Authorization");
const apiKey = extractApiKey(request);
if (authHeader && apiKey) {
const masked = log.maskKey(apiKey);
log.debug("AUTH", `API Key: ${masked}`);
} else {
log.debug("AUTH", "No API key provided (local mode)");
}
// Enforce API key if enabled in settings
const settings = await getSettings();
if (settings.requireApiKey) {
if (!apiKey) {
log.warn("AUTH", "Missing API key (requireApiKey=true)");
return errorResponse(HTTP_STATUS.UNAUTHORIZED, "Missing API key");
}
const valid = await isValidApiKey(apiKey);
if (!valid) {
log.warn("AUTH", "Invalid API key (requireApiKey=true)");
return errorResponse(HTTP_STATUS.UNAUTHORIZED, "Invalid API key");
}
}
if (!modelStr) {
log.warn("CHAT", "Missing model");
return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing model");
}
// Bypass naming/warmup requests before combo rotation to avoid wasting rotation slots
const userAgent = request?.headers?.get("user-agent") || "";
const bypassResponse = handleBypassRequest(body, modelStr, userAgent, !!settings.ccFilterNaming);
if (bypassResponse) return bypassResponse.response || bypassResponse;View on GitHub (pinned to 90b52e06ff)
Solutions
- Add the key: set Authorization: Bearer <your-9router-api-key> (or x-api-key) on every request.
- Configure your OpenAI SDK client with apiKey: 'your-9router-key' — never leave it empty when requireApiKey is on.
- If local-only usage is intended, disable requireApiKey in the dashboard settings (Settings → API key enforcement).
- Verify which header extractApiKey reads for your client and that a proxy is not stripping Authorization before it reaches the gateway.
Example fix
// before
const client = new OpenAI({ baseURL: 'http://localhost:20128/v1' });
// after
const client = new OpenAI({
baseURL: 'http://localhost:20128/v1',
apiKey: process.env.NINE_ROUTER_API_KEY
}); Defensive patterns
Strategy: validation
Validate before calling
const apiKey = process.env.NINE_ROUTER_API_KEY;
if (!apiKey) throw new Error('NINE_ROUTER_API_KEY is not set; gateway has requireApiKey enabled');
headers['Authorization'] = `Bearer ${apiKey}`; Type guard
function hasApiKey(headers) {
const auth = headers['authorization'] || '';
return /^Bearer\s+\S+/.test(auth) || Boolean(headers['x-api-key']);
} Try / catch
const res = await fetch(url, { headers });
if (res.status === 401 && (await res.text()).includes('Missing API key')) {
throw new Error('Gateway requires an API key: set Authorization: Bearer <key>');
} Prevention
- Check the dashboard's requireApiKey setting before deploying clients.
- Configure apiKey in every SDK client, even for localhost.
- Fail fast at startup if the key env var is absent.
- Confirm proxies preserve the Authorization header.
When it happens
Trigger: POST to /v1/chat/completions with settings.requireApiKey=true and no Authorization header (or no x-api-key header) on the request.
Common situations: User enabled 'require API key' in the dashboard after the client was already configured without a key; SDK default (e.g. OpenAI SDK) silently omitting the key because baseURL was set but apiKey left empty; calling the endpoint from a browser or script without auth headers.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- Invalid API key
- Missing API key
- Missing API key
- qoder PAT exchange failed: ${res.status} ${text.slice(0, 200
- GitHub API error: ${error}
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/f034cb0ba4d7b3e9.
Report an issue: GitHub.