decolua/9router · error

Missing API key

Error message

Missing API key

What it means

Auth guard in handleSearch (src/sse/handlers/search.js:51): when the server setting requireApiKey is enabled and extractApiKey(request) finds no API key on the request, the handler returns HTTP 401 'Missing API key'. 9Router exposes an OpenAI-compatible gateway; once API-key enforcement is switched on in dashboard settings, every programmatic call must carry the key even from localhost.

Source

Thrown at src/sse/handlers/search.js:51

  // Accept either `provider` or `model` (UI sends `model` since provider IS the model for webSearch)
  const providerInput = body.provider || body.model;
  const query = body.query;

  log.request("POST", `${url.pathname} | ${providerInput}`);

  // Log API key (masked)
  const apiKey = extractApiKey(request);
  if (apiKey) {
    log.debug("AUTH", `API Key: ${log.maskKey(apiKey)}`);
  } 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 (!providerInput || typeof providerInput !== "string") {
    log.warn("SEARCH", "Missing provider/model");
    return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing required field: provider (or model)");
  }

  if (!query || typeof query !== "string" || !query.trim()) {
    log.warn("SEARCH", "Missing query");
    return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing required field: query");
  }

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Attach the key as Authorization: Bearer <your-9router-api-key> on the request.
  2. Alternatively send it in the x-api-key header (whichever extractApiKey supports).
  3. Verify the key matches one generated in the dashboard (API keys section) and that requireApiKey is intentionally on.
  4. If this is a trusted local-only setup, disable requireApiKey in dashboard settings.
  5. Check the reverse proxy/middleware config isn't stripping Authorization before it reaches 9Router.

Example fix

// before
await fetch(base + '/v1/search', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) });
// after
await fetch(base + '/v1/search', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.ROUTER_API_KEY}` },
  body: JSON.stringify(payload)
});
Defensive patterns

Strategy: validation

Validate before calling

const key = process.env.ROUTER_API_KEY;
if (!key) throw new Error('ROUTER_API_KEY is required: the gateway has requireApiKey enabled');
// optional pre-check
const probe = await fetch(base + '/v1/models', { headers: { Authorization: `Bearer ${key}` } });
if (probe.status === 401) throw new Error('Gateway rejects the configured API key');

Try / catch

const res = await doSearch();
if (res.status === 401) {
  const msg = await res.text();
  if (msg.includes('Missing API key')) throw new Error('Attach Authorization: Bearer <key> — requireApiKey is enabled');
  throw new Error('Auth failed: ' + msg);
}

Prevention

When it happens

Trigger: POST to the /v1 search endpoint while settings.requireApiKey === true and the request carries no API key: no Authorization: Bearer header, no x-api-key header, and no other header extractApiKey recognizes.

Common situations: Local dev scripts that worked before API-key enforcement was enabled in the dashboard; a team member toggled requireApiKey on; a reverse proxy strips the Authorization header; the client sends the key under a custom header name the gateway's extractApiKey does not read; environment changed from no-auth local mode to a shared deployment.

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


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/93770f2a6121d40b. Report an issue: GitHub.