Thanks for testing this - your container result makes sense, and I should have
noted in the report that the effect depends on the locale and on the installed
fonts. I can reproduce it on a stock 26.04 install with the unmodified package
file, so the container result is environmental rather than a counter-example. I
also checked how far the impact reaches: narrow, but real - a regression that
upstream has already fixed.
1. What goes wrong
48-spacing.conf prepends the generic name "monospace" to the request's family
list. 45-latin.conf / 60-latin.conf then expand that generic into concrete
monospace families in front of what the application asked for, and family
matching is positional. No fonts are needed to see the mutation:
$ fc-pattern -c 'JetBrainsMono NFM:spacing=100'
family[0..2] = DejaVu LGC Sans Mono, DejaVu Sans Mono, Noto Mono, ...
family[86] = JetBrainsMono NFM <- requested by the application
2. How far it actually reaches
Whether that also changes the chosen font depends on the request's lang/charset,
on which monospace fonts are installed, and on any strong-binding alias.
Measured
here with the preinstalled 2.17.1-3ubuntu1 file, untouched (I used a throw-away
config tree so the system files stay pristine):
locale fc-match 'JetBrainsMono
NFM:spacing=100'
C, C.UTF-8, en_US, de_DE, ja_JP, ko_KR, ru_RU JetBrainsMono Nerd Font Mono
zh_CN.UTF-8 DejaVu Sans Mono <- wrong
So a LANG=C.UTF-8 container with a minimal font set is expected to print the
correct font - which is what you saw. All the commands below run as-is on
2.17.1-3ubuntu1. Two reproduction paths that do not depend on the ambient
locale:
$ fc-match 'JetBrainsMono NFM:spacing=100:lang=zh-cn'
DejaVuSansMono.ttf
and with a strong-binding monospace alias (the case MR 532's description calls
out, and reasonably common in user configs):
<alias binding="strong"><family>monospace</family>
<prefer><family>DejaVu Sans Mono</family></prefer></alias>
LC_ALL=C fc-match 'JetBrainsMono NFM:spacing=100'
shipped rule -> DejaVuSansMono.ttf ; rule removed -> JetBrainsMono Nerd
Font Mono
Scope: only applications that put spacing=100 in the pattern are affected
(Ghostty does, many terminals do not), and only where the font set, locale or
aliases let the injected family win. Low importance is fine for the scope I
measured: it is a user-visible regression for a subset of users rather than a
system-wide breakage. For those users it is daily-visible, though - the terminal
falls back to DejaVu and Nerd Font / powerline glyphs break.
3. Two shortcuts in the test itself
The test used "JetBrainsMono" (JetBrains Mono) while the report is about
"JetBrainsMono NFM" (JetBrainsMono Nerd Font Mono), so the reported case was not
exercised. Separately, the rule lives in *fontconfig-config*, not fontconfig,
and
/usr/share/fontconfig/conf.avail/48-spacing.conf is not a conffile, so
`dpkg -s fontconfig` says nothing about it - `dpkg -V fontconfig-config` plus
`ls -l /etc/fonts/conf.d/48-spacing.conf` is the check.
4. Upstream status
Fixed in 2.18.2 by MR 532 (commit 1ed41a70, merged 2026-06-22). The mode is
unchanged; the object changes:
- <edit name="family" mode="prepend"><string>monospace</string></edit>
+ <edit name="genericfamily" mode="prepend"><const>monospace</const></edit>
genericfamily is new in 2.18.0 and ranks below family-strong, so an explicitly
requested family wins again while the mono hint stays available for fallback.
2.18.0 and 2.18.1 still ship the old rule, 2.18.3 is fine. No Ubuntu or Debian
series has 2.18.x yet (resolute 2.17.1-3ubuntu1, stonking/tenacious
2.17.1-5ubuntu1), so this will not be inherited in the near term.
5. Fix options for 2.17.1
genericfamily does not exist in 2.17.x, so the upstream change cannot be applied
verbatim. My original "prepend -> append" wording was too coarse, but the
one-line append is still the closest equivalent for the reported class. I built
2.18.2 locally and compared it with 2.17.1 on identical config and fonts: for 25
sampled installed families, in both C and zh_CN, append (on 2.17.1) and
genericfamily (on 2.18.2) return the same font. They differ only for
generic-name
queries, where 2.18.2 keeps the monospace hint and plain append resolves
`sans-serif:spacing=100` to a sans face. A small config-only variant that keeps
both behaviours on 2.17.1 is available if that matters.
Given no ABI change (libfontconfig.so.1) and that this is pure XML, a one-line
resolute-updates patch is verifiable with fc-match and carries no binary risk.
Would a debdiff for resolute-updates be welcome, or would you rather wait for a
2.18.x merge? Either is a fair call; if waiting is preferred, I would just ask
that the report stays open for the affected locale/aliasing case rather than
being closed as not-a-bug.
Thanks!
Note: I used an AI assistant to help analyse this and draft the comment; every
command and output above was run and verified on my own 26.04 system.
** Patch added: "debdiff for 2.17.1-3ubuntu1 -> 2.17.1-3ubuntu1.1 (resolute)"
https://bugs.launchpad.net/ubuntu/+source/fontconfig/+bug/2169400/+attachment/6011163/+files/fontconfig_2.17.1-3ubuntu1.1.debdiff
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2169400
Title:
fontconfig 2.17.1: 48-spacing.conf overrides the application-selected
font family
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/fontconfig/+bug/2169400/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs