{"record":{"id":"f7adb960225c0022","repo":"upstash/context7","slug":"authentication-discovery-was-redirected-pass-the-final","errorCode":null,"errorMessage":"Authentication discovery was redirected. Pass the final deployment URL instead of ${deployment.baseUrl}.","messagePattern":"Authentication discovery was redirected\\. Pass the final deployment URL instead of (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/setup/deployment.ts","lineNumber":63,"sourceCode":"\nexport function getMcpUrl(deployment: SetupDeployment, auth: AuthOptions): string {\n  if (deployment.kind === \"hosted\") {\n    return auth.mode === \"oauth\"\n      ? `${HOSTED_MCP_BASE_URL}/mcp/oauth`\n      : `${HOSTED_MCP_BASE_URL}/mcp`;\n  }\n  return `${deployment.baseUrl}/mcp`;\n}\n\nexport async function getOnPremMcpAuthStatus(deployment: CustomSetupDeployment): Promise<boolean> {\n  const response = await fetch(`${deployment.baseUrl}/api/auth/mcp`, {\n    headers: { Accept: \"application/json\" },\n    redirect: \"manual\",\n    signal: AbortSignal.timeout(10_000),\n  });\n\n  if (response.status >= 300 && response.status < 400) {\n    throw new Error(\n      `Authentication discovery was redirected. Pass the final deployment URL instead of ${deployment.baseUrl}.`\n    );\n  }\n\n  if (!response.ok) {\n    throw new Error(`HTTP ${response.status} from ${deployment.baseUrl}/api/auth/mcp`);\n  }\n\n  const body = (await response.json()) as { enabled?: unknown };\n  if (typeof body.enabled !== \"boolean\") {\n    throw new Error(`Invalid response from ${deployment.baseUrl}/api/auth/mcp`);\n  }\n  return body.enabled;\n}\n","sourceCodeStart":45,"sourceCodeEnd":78,"githubUrl":"https://github.com/upstash/context7/blob/4416fb855b8f752be735e34f943b5d0762701aad/packages/cli/src/setup/deployment.ts#L45-L78","documentation":"Thrown by getOnPremMcpAuthStatus when the GET to `${deployment.baseUrl}/api/auth/mcp` (fetched with redirect: 'manual') returns a 3xx redirect. Because authentication discovery follows redirects would hide a misconfigured base URL, the CLI fails fast and asks for the final deployment URL.","triggerScenarios":"getOnPremMcpAuthStatus(deployment) is called (via resolveAuth) for a custom deployment and the auth discovery endpoint responds with status 300-399 — typically an HTTP→HTTPS or host rewrite redirect.","commonSituations":"On-prem server redirects http:// to https://; a load balancer or ingress rewrites to a canonical hostname or adds/removes a path prefix; a trailing-slash redirect at the proxy.","solutions":["Follow the redirect manually (curl -I) and re-run setup with the final destination URL.","Prefer the https:// canonical host if the redirect was scheme upgrade.","Fix reverse-proxy/ingress rewrite rules so the configured URL is served directly without redirecting."],"exampleFix":"// before\nctx7 setup --url http://my-onprem.internal   # 301 -> https://my-onprem.internal\n\n// after\ncurl -sI http://my-onprem.internal/api/auth/mcp   # note Location header\nctx7 setup --url https://my-onprem.internal","handlingStrategy":"validation","validationCode":"// Pre-check that the discovery endpoint is served without a redirect:\nconst res = await fetch(`${base}/api/auth/mcp`, { redirect: 'manual' });\nif (res.status >= 300 && res.status < 400) {\n  throw new Error(`Use the final URL: ${res.headers.get('location')}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const enabled = await getOnPremMcpAuthStatus(deployment);\n} catch (e) {\n  if ((e as Error).message.includes('redirected')) {\n    console.error('Resolve the redirect (curl -I) and pass the final https URL.');\n  }\n}","preventionTips":["Configure the canonical https URL of the deployment, not a redirecting alias.","Check ingress/proxy rules for rewrites on the configured hostname.","Verify with `curl -sI <base>/api/auth/mcp` expecting 200, not 3xx."],"tags":["http","redirect","configuration","network"],"backgroundTag":"unexpected-http-status","analyzedSha":"4416fb855b8f752be735e34f943b5d0762701aad","analyzedAt":"2026-09-16T20:28:07.148Z","contentChangedAt":"2026-09-16T20:28:07.148Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}