Home / Alt manpages / fc-validate(1)

  • fc-validate(1)
  • User command
  • linux

Validate Font Coverage with fc-validate

You will finish with a repeatable check that a font file satisfies fontconfig's language coverage rules, plus a way to test one face when a file contains several. The examples use fc-validate from fontconfig 2.15.0, installed here as package version 2.15.0-1.1ubuntu2.

Allow about ten minutes. You need a shell, a readable font file and the fontconfig utilities already installed. The checks are read-only: they do not install fonts, rebuild caches or alter font configuration. Run them as an ordinary user unless the font file itself is not readable.

1. Check the installed command

Start by confirming which executable will run and recording its version. These are ordinary, read-only commands and do not need elevated privileges:

$ command -v fc-validate
/usr/bin/fc-validate
$ fc-validate --version
fontconfig version 2.15.0

The command accepts one or more font files. Its short options are -i or --index for a face index, -l or --lang for a language, -v or --verbose for more detail, and -V or --version. Ask the installed binary for the complete summary if you are working on another host:

$ fc-validate --help
usage: fc-validate [-Vhv] [-i index] [-l LANG] [--index index] [--lang LANG] [--verbose] [--version] [--help] font-file...

2. Validate one font file

Choose a real, readable font rather than guessing a path. This example uses a font shipped on the machine running this guide:

$ FONT_FILE=/usr/share/fonts/truetype/liberation/LiberationSansNarrow-Italic.ttf
$ test -r "$FONT_FILE" && echo "readable: $FONT_FILE"
readable: /usr/share/fonts/truetype/liberation/LiberationSansNarrow-Italic.ttf
$ fc-validate "$FONT_FILE"
/usr/share/fonts/truetype/liberation/LiberationSansNarrow-Italic.ttf:0 Satisfy the coverage for en language

The output identifies the file, the face index, and the language coverage result. The default language comes from the current locale. On this host the locale selects English, so the result mentions en. Do not treat that language as a universal default: the same command can produce a different result on a host with a different locale.

Checkpoint

Capture the exit status immediately after the validation:

$ printf 'exit status: %s\n' "$?"
exit status: 0

Status 0 means the font was parsed successfully and the checked faces satisfied the requested coverage. Status 1 means an error occurred or at least one face could not be opened. The message is useful evidence, but scripts should also check the status.

3. Validate several files in one run

Pass more than one path as separate arguments. Avoid an unquoted wildcard when a directory may contain names with spaces; a shell array keeps each path intact:

$ fonts=(/usr/share/fonts/truetype/liberation/*.ttf)
$ fc-validate "${fonts[@]}"
/usr/share/fonts/truetype/liberation/LiberationMono-Bold.ttf:0 Satisfy the coverage for en language
/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf:0 Satisfy the coverage for en language

Your list and output will differ. If the wildcard matches nothing, some shells pass the literal pattern and validation fails. Check the list first when using this in automation:

$ printf '%s\n' "${fonts[@]}"
$ ((${#fonts[@]} > 0)) || { echo 'no font files found' >&2; exit 1; }

Keep the exit status from fc-validate itself. A later diagnostic command replaces $?, so store it if you need to print more information.

4. Select one face from a font collection

A font file can contain multiple faces. Without --index, fc-validate validates all faces. Use a numeric index when you need to isolate one face:

$ fc-validate --index 0 /path/to/font-file.ttf
/path/to/font-file.ttf:0 Satisfy the coverage for en language

The index is zero-based in the displayed result. Do not assume that index 0 is the face you want in a collection. Run the command without --index first, then use the reported face numbers and the font's own metadata to decide what to test. An index that does not exist is an input error and returns status 1.

5. Test a specific language

Use --lang when the current locale is not the language requirement you need to check:

$ fc-validate --lang en /usr/share/fonts/truetype/liberation/LiberationSansNarrow-Italic.ttf
/usr/share/fonts/truetype/liberation/LiberationSansNarrow-Italic.ttf:0 Satisfy the coverage for en language
$ printf 'exit status: %s\n' "$?"
exit status: 0

Use the language identifier expected by your fontconfig installation, such as en for English. This option changes the language used for the check; it does not edit the locale, the font file or fontconfig's installed orthography data. If you need the normal locale-driven behaviour again, omit --lang.

6. Diagnose a failed validation

First distinguish an unreadable or missing file from a coverage failure. These checks do not change anything:

$ FONT_FILE=/path/to/font-file.ttf
$ ls -l "$FONT_FILE"
$ test -r "$FONT_FILE" && echo readable
$ fc-validate "$FONT_FILE"
Unable to open /path/to/font-file.ttf
$ printf 'exit status: %s\n' "$?"
exit status: 1

Correct the path or file permissions through your normal system process. Use sudo only if the file is intentionally restricted and you are authorised to read it. Do not use elevated privileges as a general fix for a font that fails language coverage.

If a file opens but fails validation, rerun with the intended --lang value and, for a collection, each relevant --index. --verbose may provide more detailed information, although a simple font can still produce the same single-line result:

$ fc-validate --verbose "$FONT_FILE"
/path/to/font-file.ttf:0 Satisfy the coverage for en language

Do not delete or replace a font as part of this diagnostic. A validation result describes the file against the selected language rules; it is not an instruction to change system fonts or rebuild a cache.

Done means

  • You confirmed the installed fontconfig version and executable.
  • You validated a readable font and checked the exit status.
  • You know that all faces are checked unless --index selects one.
  • You used --lang when the host locale was not the requirement.
  • You can separate a missing or unreadable file from a coverage result.
  • No font file, cache, locale or persistent configuration was changed.