unslothai/unsloth · error

Provider public key is missing.

Error message

Provider public key is missing.

What it means

Thrown by importProviderPublicKey when GET /api/providers/public-key succeeded (2xx) but the returned public_key field is missing, empty, or whitespace-only after trim. This blocks the RSA key import (forge.pki.publicKeyFromPem) used to encrypt provider API keys client-side; without it no provider key can be saved.

Source

Thrown at studio/frontend/src/features/chat/api/providers-api.ts:114

let cachedPublicKeyPem: string | null = null;
let cachedForgeKey: forge.pki.rsa.PublicKey | null = null;

export function clearProviderPublicKeyCache(): void {
  cachedPublicKeyPem = null;
  cachedForgeKey = null;
}

async function importProviderPublicKey(
  forceRefresh = false,
): Promise<forge.pki.rsa.PublicKey> {
  if (!forceRefresh && cachedForgeKey) {
    return cachedForgeKey;
  }
  const response = await authFetch("/api/providers/public-key");
  const body = await parseJsonOrThrow<{ public_key: string }>(response);
  const publicKeyPem = body.public_key?.trim();
  if (!publicKeyPem) {
    throw new Error("Provider public key is missing.");
  }
  if (!forceRefresh && cachedPublicKeyPem === publicKeyPem && cachedForgeKey) {
    return cachedForgeKey;
  }
  const forgeKey = forge.pki.publicKeyFromPem(publicKeyPem);
  cachedPublicKeyPem = publicKeyPem;
  cachedForgeKey = forgeKey;
  return forgeKey;
}

export async function encryptProviderApiKey(
  plaintextApiKey: string,
  forceRefresh = false,
): Promise<string> {
  const key = await importProviderPublicKey(forceRefresh);
  const encrypted = key.encrypt(plaintextApiKey, "RSA-OAEP", {
    md: forge.md.sha256.create(),
    mgf1: { md: forge.md.sha256.create() },

View on GitHub (pinned to 203007d190)

Solutions

  1. Fix the backend so /api/providers/public-key returns a valid PEM — check server startup logs for keypair generation errors.
  2. Verify the server has write access to persist its generated keypair so it is stable across restarts (a rotating key would also break decryption of stored keys).
  3. Retry saving the provider once the endpoint returns a non-empty key.
Defensive patterns

Strategy: validation

Validate before calling

const probe = await authFetch('/api/providers/public-key');
const key = (await probe.json()).public_key;
if (!key || !key.trim()) throw new Error('Backend keypair not configured — fix server setup');

Try / catch

try { await encryptProviderApiKey(apiKey); }
catch (e) {
  if (e.message === 'Provider public key is missing.') showServerSetupHint();
  else throw e;
}

Prevention

When it happens

Trigger: Server returns {public_key: ''} or omits the field — misconfigured backend that failed to generate/load its RSA keypair at startup.

Common situations: Backend started without generating a keypair (missing write permission for the key file, first-run setup incomplete); key migration/rotation left the config empty; a custom deployment skipping an init step.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/8d09751c21aa8709. Report an issue: GitHub.