musistudio/claude-code-router · error · Error
Grok CLI OIDC discovery returned HTTP ${response.status}${to
Error message
Grok CLI OIDC discovery returned HTTP ${response.status}${tokenRefreshErrorMessage(payload, text)} What it means
During Grok OIDC discovery, the well-known configuration endpoint returned a non-2xx status. The message includes the status code and any parseable error detail, thrown before a token endpoint can be resolved for the refresh flow.
Source
Thrown at packages/core/src/agents/local-providers/grok.ts:749
async function grokTokenEndpoint(auth: GrokTokenSet): Promise<string> {
const configured = readString(process.env.GROK_OIDC_TOKEN_ENDPOINT);
if (configured) {
return configured;
}
const issuer = (auth.oidcIssuer || readString(process.env.GROK_OIDC_ISSUER) || grokDefaultOidcIssuer).replace(/\/+$/, "");
const metadataUrl = `${issuer}/.well-known/openid-configuration`;
const timeoutMs = normalizeGrokOauthTimeout(process.env.GROK_OIDC_REFRESH_TIMEOUT_MS);
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetchWithSystemProxy(metadataUrl, {
headers: { accept: "application/json" },
signal: controller.signal
});
const text = await response.text();
const payload = parseJsonRecord(text);
if (!response.ok) {
throw new Error(`Grok CLI OIDC discovery returned HTTP ${response.status}${tokenRefreshErrorMessage(payload, text)}`);
}
const tokenEndpoint = readString(payload?.token_endpoint) || readString(payload?.tokenEndpoint);
if (!tokenEndpoint) {
throw new Error("Grok CLI OIDC discovery did not return a token endpoint.");
}
return tokenEndpoint;
} catch (error) {
if (error instanceof Error && error.name === "AbortError") {
throw new Error(`Grok CLI OIDC discovery timed out after ${timeoutMs}ms.`);
}
throw error;
} finally {
clearTimeout(timer);
}
}
function grokCredentialFiles(): string[] {
const explicitFile = process.env.GROK_AUTH_FILE?.trim();View on GitHub (pinned to 99f24806c6)
Solutions
- Re-run login to refresh the cached discovery/issuer URL
- curl the discovery URL to confirm what status the host returns
- Check for proxy/VPN interference on the discovery host
- Retry — 5xx discovery failures are often transient
Defensive patterns
Strategy: retry
Validate before calling
const discoveryOk = await fetch(discoveryUrl, { method: 'HEAD' }).then(r => r.ok).catch(() => false);
if (!discoveryOk) deferProviderImport(); Try / catch
catch (e) {
if (e instanceof Error && e.message.startsWith('Grok CLI OIDC discovery returned HTTP')) {
const status = Number(e.message.match(/HTTP (\d+)/)?.[1]);
if (status >= 500 || status === 429) await retryWithBackoff();
else await refreshDiscoveryConfig();
}
} Prevention
- Cache the discovered token endpoint so discovery is not re-run every refresh
- Treat discovery 4xx as configuration drift, not transient failure
When it happens
Trigger: fetching the OIDC discovery/well-known URL returns !response.ok — wrong/rotated discovery URL, 404 from a host that no longer serves discovery, or a 5xx during provider outage.
Common situations: The provider changed its OIDC issuer/host and cached configuration points to the old URL; regional endpoints differ; a proxy returns 407/502 for the discovery host.
Related errors
- Grok CLI OIDC discovery did not return a token endpoint.
- Grok CLI OIDC discovery timed out after ${timeoutMs}ms.
- Grok CLI OAuth token refresh did not return an access token.
- Grok CLI OAuth token refresh timed out after ${timeoutMs}ms.
- Kimi CLI OAuth token refresh returned HTTP ${response.status
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/5f1a115bf0d91488.
Report an issue: GitHub.