decolua/9router · warning · Error
`xai discovery ${field} host ${host} is not on x.ai`
Error message
`xai discovery ${field} host ${host} is not on x.ai` What it means
validateXaiOAuthEndpoint allowlists endpoint hosts: the hostname must be exactly 'x.ai' or a subdomain ending in '.x.ai'. Any other host (including lookalikes like xai.com, evil-x.ai, or an IP address) is rejected with this error naming the field and offending host. This blocks phishing/token-exfiltration via a compromised discovery document; discoverXaiEndpoints catches it and falls back to static x.ai endpoints.
Source
Thrown at src/lib/oauth/providerHelpers.js:13
const BASE64_BLOCK_SIZE = 4;
function validateXaiOAuthEndpoint(rawUrl, field) {
const value = String(rawUrl || "").trim();
if (!value) throw new Error(`xai discovery ${field} is empty`);
let parsed;
try { parsed = new URL(value); } catch (err) {
throw new Error(`xai discovery ${field} is invalid: ${err.message}`);
}
if (parsed.protocol !== "https:") throw new Error(`xai discovery ${field} must use https: ${value}`);
const host = parsed.hostname.toLowerCase().trim();
if (host !== "x.ai" && !host.endsWith(".x.ai")) {
throw new Error(`xai discovery ${field} host ${host} is not on x.ai`);
}
return value;
}
function decodeXaiIdTokenEmail(idToken) {
if (!idToken || typeof idToken !== "string") return undefined;
const parts = idToken.split(".");
if (parts.length !== 3) return undefined;
try {
const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
const padding = (BASE64_BLOCK_SIZE - (base64.length % BASE64_BLOCK_SIZE)) % BASE64_BLOCK_SIZE;
const json = Buffer.from(base64 + "=".repeat(padding), "base64").toString("utf8");
const payload = JSON.parse(json);
return payload.email || payload.preferred_username || payload.sub || undefined;
} catch {
return undefined;
}
}View on GitHub (pinned to 90b52e06ff)
Solutions
- Use the official discovery URL so endpoints resolve to x.ai hosts; drop any custom discoveryUrl override.
- Accept the built-in static fallback endpoints in discoverXaiEndpoints.
- If you legitimately need a different host (e.g. corporate proxy), you must fork/extend the allowlist rather than passing the URL through.
- Investigate DNS/proxy tampering if the host changed unexpectedly.
Example fix
// before
validateXaiOAuthEndpoint('https://auth.xai-mirror.example.com/token', 'token_endpoint'); // throws: host is not on x.ai
// after
validateXaiOAuthEndpoint('https://auth.x.ai/token', 'token_endpoint'); Defensive patterns
Strategy: validation
Validate before calling
function isXaiHost(v) {
try {
const h = new URL(String(v).trim()).hostname.toLowerCase();
return h === 'x.ai' || h.endsWith('.x.ai');
} catch { return false; }
}
// if (!isXaiHost(data.token_endpoint)) use static x.ai endpoints Type guard
function isXaiEndpoint(v) {
if (typeof v !== 'string') return false;
try {
const u = new URL(v.trim());
if (u.protocol !== 'https:') return false;
const h = u.hostname.toLowerCase();
return h === 'x.ai' || h.endsWith('.x.ai');
} catch { return false; }
} Try / catch
try {
const url = validateXaiOAuthEndpoint(raw, 'authorization_endpoint');
// use url
} catch (err) {
if (/is not on x\.ai/.test(err.message)) {
// suspected tampering/mirror — use official static endpoints and alert
console.error('xAI discovery host rejected:', err.message);
return XAI_CONFIG.authorizeUrl;
}
throw err;
} Prevention
- Never point discoveryUrl at third-party xAI-compatible mirrors in production.
- Monitor DNS/proxy health; unexpected hostnames usually indicate hijacking.
- Keep the host allowlist intact — do not 'fix' this error by loosening it to an untrusted host.
- Pin the static x.ai endpoints so any discovery failure degrades safely.
When it happens
Trigger: Discovery response advertises authorization_endpoint/token_endpoint on a foreign host, or a developer points discoveryUrl at a mirror whose endpoints live on another domain.
Common situations: Third-party xAI-compatible proxies, DNS hijacking or captive portals rewriting hostnames, DNS-based content filters, or security tests verifying the allowlist.
Related errors
- xai discovery ${field} host ${host} is not on x.ai
- token_endpoint must be a Microsoft login endpoint
- xai discovery ${field} is empty
- xai discovery ${field} is invalid: ${err.message}
- `xai discovery ${field} must use https: ${value}`
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/aceceeed408abe72.
Report an issue: GitHub.