janhq/jan · error

Authentication failed: API key is required or invalid for

Error message

Authentication failed: API key is required or invalid for ${provider.provider}

What it means

fetchModelsFromProvider throws this when the provider's /models endpoint responds with HTTP 401. It means the API key sent (via x-api-key / Authorization: Bearer headers) is missing, empty, expired, or rejected by the provider. The code tries each configured key attempt on 401/403/429 before giving up with this error.

Solutions

  1. Open provider settings and enter a valid API key for the selected provider (it is stored in the OS keyring).
  2. Verify the key works with a direct curl call to the provider's /models endpoint.
  3. If using a self-hosted/proxy endpoint that needs no auth, confirm the provider type matches the endpoint so keys/headers are sent correctly.
  4. Regenerate the key on the provider dashboard if it was rotated or revoked.

Example fix

// before: provider saved without a key
{ provider: 'openai', base_url: 'https://api.openai.com/v1', api_key: '' }
// after
{ provider: 'openai', base_url: 'https://api.openai.com/v1', api_key: 'sk-<valid-key>' }
Defensive patterns

Strategy: validation

Validate before calling

if (!provider.api_key || provider.api_key.trim() === '' || provider.api_key.startsWith('sk-...')) {
  throw new Error(`Configure a valid API key for ${provider.provider} before fetching models`)
}

Type guard

function hasApiKey(p: { api_key?: string | null }): p is typeof p & { api_key: string } {
  return typeof p.api_key === 'string' && p.api_key.trim().length > 0
}

Try / catch

try {
  await fetchModelsFromProvider(provider)
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Authentication failed')) {
    openProviderSettings(provider.provider) // prompt user to fix the key
  }
}

Prevention

When it happens

Trigger: GET `${provider.base_url}/models` returned 401 after exhausting all keyAttempts; happens when no API key is configured for a hosted provider, or the configured key is invalid/expired/revoked.

Common situations: Using Jan with OpenAI/Anthropic without pasting an API key in settings; key rotated or revoked upstream; wrong provider selected so the key is sent to a different vendor; trailing whitespace or placeholder key ('sk-...') saved in settings; self-hosted server requiring auth the app doesn't know about.

Understand the failure class

Related errors


AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17). Data as JSON: /api/errors/718fc16f1fe48e05. Report an issue: GitHub.

Appendix: source

Thrown at web-app/src/services/providers/tauri.ts:203

        const response = await fetchTauri(`${provider.base_url}/models`, {
          method: 'GET',
          headers,
        })

        lastStatus = response.status
        lastStatusText = response.statusText

        if (
          [401, 403, 429].includes(response.status) &&
          ki < keyAttempts.length - 1
        ) {
          continue
        }

        if (!response.ok) {
          if (response.status === 401) {
            throw new Error(
              `Authentication failed: API key is required or invalid for ${provider.provider}`
            )
          }
          if (response.status === 403) {
            throw new Error(
              `Access forbidden: Check your API key permissions for ${provider.provider}`
            )
          }
          if (response.status === 404) {
            throw new Error(
              `Models endpoint not found for ${provider.provider}. Check the base URL configuration.`
            )
          }
          throw new Error(
            `Failed to fetch models from ${provider.provider}: ${response.status} ${response.statusText}`
          )
        }

View on GitHub (pinned to 7205d770c1)