{"record":{"id":"8b6dbafd801fbf18","repo":"tobi/qmd","slug":"downloaded-model-file-is-an-html-page-not-a-gguf","errorCode":null,"errorMessage":"Downloaded model file is an HTML page, not a GGUF model (${formatModelFileSize(inspection.sizeBytes ?? 0)}).\\nSomething is intercepting the download from huggingface.co (a proxy, firewall, or captive portal).\\n\\nModel: ${modelUri}\\nPath:  ${filePath}\\n\\nTo fix this, either:\\n  1. Try a HuggingFace mirror:  HF_ENDPOINT=https://hf-mirror.com qmd embed\\n  2. Download the model manually and set the env var, e.g.:\\n       QMD_EMBED_MODEL=/path/to/model.gguf qmd embed\\n\\nNote: 'qmd search' works without any model downloads.","messagePattern":"Downloaded model file is an HTML page, not a GGUF model \\((.+?)\\)\\.\\\\nSomething is intercepting the download from huggingface\\.co \\(a proxy, firewall, or captive portal\\)\\.\\\\n\\\\nModel: (.+?)\\\\nPath:  (.+?)\\\\n\\\\nTo fix this, either:\\\\n  1\\. Try a HuggingFace mirror:  HF_ENDPOINT=https://hf-mirror\\.com qmd embed\\\\n  2\\. Download the model manually and set the env var, e\\.g\\.:\\\\n       QMD_EMBED_MODEL=/path/to/model\\.gguf qmd embed\\\\n\\\\nNote: 'qmd search' works without any model downloads\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/llm.ts","lineNumber":463,"sourceCode":"  }\n}\n\n/**\n * Validate that a file is actually a GGUF model, not an HTML error page\n * from a proxy, firewall, or failed download.\n * Throws a descriptive error if the file is not valid GGUF.\n */\nfunction validateGgufFile(filePath: string, modelUri: string): void {\n  const inspection = inspectGgufFile(filePath);\n  if (!inspection.exists || inspection.valid) return; // let downstream handle missing files\n\n  // Remove the bad file so the next attempt re-downloads\n  try {\n    unlinkSync(filePath);\n  } catch { /* best effort */ }\n\n  if (inspection.kind === \"html\") {\n    throw new Error(\n      `Downloaded model file is an HTML page, not a GGUF model (${formatModelFileSize(inspection.sizeBytes ?? 0)}).\\n` +\n      `Something is intercepting the download from huggingface.co (a proxy, firewall, or captive portal).\\n\\n` +\n      `Model: ${modelUri}\\n` +\n      `Path:  ${filePath}\\n\\n` +\n      `To fix this, either:\\n` +\n      `  1. Try a HuggingFace mirror:  HF_ENDPOINT=https://hf-mirror.com qmd embed\\n` +\n      `  2. Download the model manually and set the env var, e.g.:\\n` +\n      `       QMD_EMBED_MODEL=/path/to/model.gguf qmd embed\\n\\n` +\n      `Note: 'qmd search' works without any model downloads.`\n    );\n  }\n\n  throw new Error(\n    `Model file is not valid GGUF (expected magic \"GGUF\", got \"${inspection.magic ?? \"unknown\"}\", file is ${formatModelFileSize(inspection.sizeBytes ?? 0)}).\\n` +\n    `Model: ${modelUri}\\n` +\n    `Path:  ${filePath}\\n\\n` +\n    `The file has been removed. Run the command again to re-download.`\n  );","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/tobi/qmd/blob/dbfd0b4736aeaf761d1a16ca8e424f071df8feb9/src/llm.ts#L445-L481","documentation":"After downloading a GGUF model from huggingface.co, validation found the file is actually an HTML page — typical of a proxy, captive portal, or firewall intercepting the download. The bad file is deleted automatically so a retry re-downloads, and the error suggests a mirror or manual download via QMD_EMBED_MODEL.","triggerScenarios":"Running `qmd embed` (or resolveModel/pullModels) on a network where huggingface.co responses are intercepted: corporate proxies, hotel/airport captive portals, or DNS-level blocks in some regions.","commonSituations":"Corporate networks with SSL inspection; China/GFW blocking huggingface.co; misconfigured HTTP_PROXY returning an error page; CI runners with restricted egress.","solutions":["Retry with a mirror: HF_ENDPOINT=https://hf-mirror.com qmd embed","Download the GGUF manually and point at it: QMD_EMBED_MODEL=/path/to/model.gguf qmd embed","Configure proxy env vars (HTTPS_PROXY) correctly or whitelist huggingface.co","Remember qmd search (BM25) works with no model at all"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Preflight: can we reach huggingface.co un-intercepted?\nconst res = await fetch('https://huggingface.co', { method: 'HEAD' });\nconst contentType = res.headers.get('content-type') ?? '';\nconst likelyIntercepted = !res.ok || contentType.includes('text/html');","typeGuard":null,"tryCatchPattern":"try {\n  await runEmbed();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('HTML page')) {\n    // retry with HF_ENDPOINT=https://hf-mirror.com or prompt for QMD_EMBED_MODEL path\n  } else throw e;\n}","preventionTips":["Set HTTPS_PROXY correctly on corporate networks","Pre-download models and pin QMD_EMBED_MODEL to a local path for offline/CI use","Use qmd search (BM25) when models are unavailable"],"tags":["network","model-download","proxy","gguf","huggingface"],"backgroundTag":"download-intercepted-by-proxy","analyzedSha":"dbfd0b4736aeaf761d1a16ca8e424f071df8feb9","analyzedAt":"2026-08-28T18:07:46.628Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}