gohugoio/hugo · error
invalid font source: %s
Error message
invalid font source: %s
What it means
Thrown by images.Text when the `font` option resolves to a value that implements the `error` interface (filters.go:115-117). This indicates the font resource itself failed to load/resolve and the error object was passed through instead of a usable font source, so the filter refuses to proceed.
Source
Thrown at resources/images/filters.go:116
tf.x = cast.ToInt(v)
case "y":
tf.y = cast.ToInt(v)
case "alignx":
tf.alignx = cast.ToString(v)
if tf.alignx != "left" && tf.alignx != "center" && tf.alignx != "right" {
panic("alignx must be one of left, center, right")
}
case "aligny":
tf.aligny = cast.ToString(v)
if tf.aligny != "top" && tf.aligny != "center" && tf.aligny != "bottom" {
panic("aligny must be one of top, center, bottom")
}
case "linespacing":
tf.linespacing = cast.ToInt(v)
case "font":
if err, ok := v.(error); ok {
panic(fmt.Sprintf("invalid font source: %s", err))
}
fontSource, ok1 := v.(hugio.ReadSeekCloserProvider)
identifier, ok2 := v.(resource.Identifier)
if !(ok1 && ok2) {
panic(fmt.Sprintf("invalid text font source: %T", v))
}
tf.fontSource = fontSource
// The input value isn't hashable and will not make a stable key.
// Replace it with a string in the map used as basis for the
// hash string.
opt["font"] = identifier.Key()
}
}
}View on GitHub (pinned to 52c9bd7908)
Solutions
- Check the font resource for an error before passing it to images.Text.
- Verify the font file exists under assets/ and the path used in resources.Get is correct.
- If fetching remotely, confirm the URL returns 200 and a valid font before forwarding it.
Example fix
// before
{{ $f := resources.GetRemote "https://example.com/font.woff" }}
{{ $filters = $filters | append (images.Text "Hi" (dict "font" $f)) }}
// after
{{ $f := resources.GetRemote "https://example.com/font.woff" }}
{{ if $f.Err }}{{ errorf "font load failed: %v" $f.Err }}{{ end }}
{{ $filters = $filters | append (images.Text "Hi" (dict "font" $f)) }} Defensive patterns
Strategy: validation
Validate before calling
{{ $f := resources.GetRemote "https://example.com/font.woff" }}
{{ with $f.Err }}
{{ errorf "font fetch failed: %v" . }}
{{ end }} Type guard
// AsError reports whether v carries a load error (implements error).
func AsError(v any) bool { _, ok := v.(error); return ok } Prevention
- Always check resources.GetRemote/.Err and resources.FromString errors before forwarding to Text.
- Log the underlying font error so the cause is visible.
- Provide a fallback font resource when the primary may fail.
When it happens
Trigger: Passing a resource lookup that returned an error (e.g. a failed resources.Get or a malformed resources.GetRemote result) directly as the `font` argument. The type switch detects the error type first and panics with the underlying error message.
Common situations: Font file is missing from assets/, the path is wrong, GetRemote returned a non-200 response whose error is forwarded, or a resources.Concat/FromString produced an error that was not checked before being handed to Text.
Related errors
- invalid text font source: %T
- aligny must be one of top, center, bottom
- failed to decode image: %s
- failed to decode image: %s
- the padding filter requires between 1 and 5 arguments
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/198f6c8f1cd471c5.
Report an issue: GitHub.