{"record":{"id":"fd2db7da02a72fd8","repo":"withastro/astro","slug":"cannotfetchfontfile","errorCode":"CannotFetchFontFile","errorMessage":"An error occurred while fetching the font file from ${url}.","messagePattern":"An error occurred while fetching the font file from (.+?)\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/assets/fonts/infra/cached-font-fetcher.ts","lineNumber":47,"sourceCode":"\t\t}\n\t\tconst data = await cb();\n\t\tawait storage.setItemRaw(key, data);\n\t\treturn data;\n\t}\n\n\tasync fetch({ id, url, init }: FontFileData): Promise<Buffer> {\n\t\treturn await this.#cache(this.#storage, id, async () => {\n\t\t\ttry {\n\t\t\t\tif (isAbsolute(url)) {\n\t\t\t\t\treturn await this.#readFile(url);\n\t\t\t\t}\n\t\t\t\tconst response = await this.#fetch(url, init ?? undefined);\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Response was not successful, received status code ${response.status}`);\n\t\t\t\t}\n\t\t\t\treturn Buffer.from(await response.arrayBuffer());\n\t\t\t} catch (cause) {\n\t\t\t\tthrow new AstroError(\n\t\t\t\t\t{\n\t\t\t\t\t\t...AstroErrorData.CannotFetchFontFile,\n\t\t\t\t\t\tmessage: AstroErrorData.CannotFetchFontFile.message(url),\n\t\t\t\t\t},\n\t\t\t\t\t{ cause },\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n}\n","sourceCodeStart":29,"sourceCodeEnd":58,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/assets/fonts/infra/cached-font-fetcher.ts#L29-L58","documentation":"Thrown by CachedFontFetcher.fetch when retrieving a font file fails. The fetcher first tries to read an absolute path from disk via readFile; otherwise it issues an HTTP request. Any failure (non-2xx status, network error, filesystem read error, or an unreadable response body) is wrapped in an AstroError with code CannotFetchFontFile, preserving the original cause.","triggerScenarios":"Calling fetch({ id, url, init }) where url is a remote URL that returns a non-OK status (response.ok is false), or the network call rejects, or url is an absolute filesystem path that readFileSync cannot open. Any exception thrown inside the try block (including a thrown Error for status codes) is caught and rethrown as CannotFetchFontFile with the offending url interpolated.","commonSituations":"A font provider URL is unreachable due to a corporate proxy, a typo'd family/weight URL, the font CDN returning 403/404, the build host lacking egress to fonts.googleapis.com / fonts.gstatic.com, or a local file path that does not exist or has wrong permissions during build.","solutions":["Check network egress from the build/host environment to the font source host (curl the exact url from the error).","Verify the URL is correct and the font family/weight exists on the remote provider; a 404/403 will trigger this.","If the URL is a local absolute path, confirm the file exists and is readable by the build process.","Pass a custom init (RequestInit) with headers/proxy if behind a corporate proxy or needing a User-Agent.","Inspect the `cause` on the thrown AstroError for the underlying fetch/filesystem error detail."],"exampleFix":"// before\nexperimentalSvgFonts({ families: [{ name: 'My Font', weight: 999 }] })\n\n// after - verify the exact URL resolves before building\nconst res = await fetch('https://fonts.gstatic.com/.../myfont.woff2');\nif (!res.ok) throw new Error(`font ${res.status}`);","handlingStrategy":"try-catch","validationCode":"// Validate the URL before fetching\nimport { isAbsolute } from 'node:path';\nfunction isValidFontUrl(url: string): boolean {\n  try {\n    if (isAbsolute(url)) return true; // local path handled by fs\n    const u = new URL(url);\n    return u.protocol === 'http:' || u.protocol === 'https:';\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const buf = await fontFetcher.fetch({ id, url });\n} catch (e) {\n  if (e instanceof AstroError && e.code === 'CannotFetchFontFile') {\n    // inspect e.cause for the underlying fetch/fs error; retry with a fallback provider\n  }\n  throw e;\n}","preventionTips":["Smoke-test font URLs (curl -I) in the build environment before building.","Pin font provider URLs to a stable CDN host.","Cache font files locally as a fallback for airgapped/offline builds.","Ensure the build host has egress to the font provider domain."],"tags":["fonts","network","fetch","build"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}