squidfunk/mkdocs-material · error · PluginError
Couldn't find font family '{family}' on Google Fonts ({res.s
Error message
Couldn't find font family '{family}' on Google Fonts ({res.status_code}: {res.reason}) What it means
`_fetch_font_from_google_fonts` downloads the font manifest from `https://fonts.google.com/download/list?family=...` when resolving a font family for social cards. Any non-200 response (font not found, rate limiting, network/proxy failure) raises this PluginError with the HTTP status and reason.
Source
Thrown at src/plugins/social/plugin.py:890
# Fall back to regular font (guess if there are multiple)
return self._resolve_font(family, fallback)
# -------------------------------------------------------------------------
# Fetch font family from Google Fonts
def _fetch_font_from_google_fonts(self, family: str):
path = os.path.join(self.config.cache_dir, "fonts")
# Download manifest from Google Fonts - Google returns JSON with syntax
# errors, so we just treat the response as plain text and parse out all
# URLs to font files, as we're going to rename them anyway. This should
# be more resilient than trying to correct the JSON syntax.
url = f"https://fonts.google.com/download/list?family={family}"
res = requests.get(url)
# Ensure that the download succeeded
if res.status_code != 200:
raise PluginError(
f"Couldn't find font family '{family}' on Google Fonts "
f"({res.status_code}: {res.reason})"
)
# Extract font URLs from manifest
for match in re.findall(
r"\"(https:(?:.*?)\.[ot]tf)\"", str(res.content)
):
with requests.get(match) as res:
res.raise_for_status()
# Construct image font for analysis by directly reading the
# contents from the response without priorily writing to a
# temporary file (like we did before), as this might lead to
# problems on Windows machines, see https://t.ly/LiF_k
with BytesIO(res.content) as f:
font = ImageFont.truetype(f)
View on GitHub (pinned to e2136532f4)
Solutions
- Verify the font family name exists on fonts.google.com and use its exact name (spaces encoded).
- For custom/local fonts, place the font files in the cache directory yourself or use a layout that references a bundled font instead of Google Fonts.
- Fix network egress: configure HTTPS_PROXY, allow fonts.google.com in the firewall, or pre-populate the plugin's font cache.
- Retry the build if the failure was a transient 429/5xx; add caching of downloaded fonts between CI runs.
Example fix
# before (mkdocs.yml, font not on Google Fonts)
- social:
cards_font: My Corporate Sans
# after: use a Google-hosted family or bundle locally
- social:
cards_font: Roboto Defensive patterns
Strategy: retry
Validate before calling
# preflight: fonts reachable and family known
def font_available(family):
import requests
r = requests.head(f"https://fonts.google.com/download/list?family={family}", timeout=10)
return r.status_code == 200 Try / catch
from mkdocs.exceptions import PluginError
import time
for attempt in range(3):
try:
return plugin._resolve_font(family, style)
except PluginError as e:
if ' 429' in str(e) or ' 50' in str(e):
time.sleep(2 ** attempt)
continue
raise Prevention
- Cache downloaded fonts between builds (persist the plugin cache directory in CI)
- Verify font families exist on fonts.google.com before adding them to layouts
- Ensure CI network egress/proxy allows fonts.google.com
- Use bundled/self-hosted fonts for hermetic builds
When it happens
Trigger: A card layout requests a font family not available on Google Fonts; no network access or a blocking proxy/firewall; Google Fonts returns 403/429 (rate limit or bot protection); family name misspelled or using a non-Google-Fonts font.
Common situations: CI environments without internet egress; corporate proxies blocking fonts.google.com; custom `cards_font` set to a self-hosted/local font that Google doesn't serve; transient 429s during batch builds.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Couldn't find layout '{name}'
- Couldn't find icon '{name}'
- Required dependencies of "social" plugin not found: {import_
- "cairosvg" Python module is installed, but it crashed with:
- Couldn't find image '{background.image}'
AI-assisted analysis of squidfunk/mkdocs-material@e2136532f4 (2026-08-29).
Data as JSON: /api/errors/4df56e8d0c95830d.
Report an issue: GitHub.