dotnet/wpf · error · FileFormatException
FileFormatException
Error message
FileFormatException
What it means
GlyphTypeface.Initialize throws System.IO.FileFormatException when DirectWrite fails to create a font face from the given URI source (fontFaceDWrite == null). This mirrors WPF 3.x behavior: passing an unsupported file — e.g. a composite font file (.compositeFont) or a path that is not a real TrueType/OpenType font — produces this exception. It means the file exists and was opened, but its contents are not a usable font face.
Solutions
- Verify the URI points to a genuine TrueType/OpenType (.ttf/.otf/.ttc) binary font, not a composite font definition file
- Open the file bytes and check for valid font signatures (0x00010000, 'OTTO', 'ttcf', 'true') before constructing GlyphTypeface
- Re-copy the font from a known-good source — the file may be truncated or corrupted
- Use a Pack URI that actually embeds the font resource in the assembly (Build Action: Resource) and confirm the resource exists
- Catch FileFormatException around GlyphTypeface construction and fall back to a bundled, verified font
Example fix
// before
glyphTypeface = new GlyphTypeface(new Uri("pack://application:,,,/Fonts/MyFont.compositeFont"));
// after
glyphTypeface = new GlyphTypeface(new Uri("pack://application:,,,/Fonts/MyFont.ttf")); Defensive patterns
Strategy: validation
Validate before calling
bool IsValidFontFile(Uri fontUri)
{
byte[] sig = new byte[4];
using (var s = File.OpenRead(fontUri.LocalPath))
{
if (s.Read(sig, 0, 4) < 4) return false;
}
return sig[0] == 0x00 && sig[1] == 0x01 && sig[2] == 0x00 && sig[3] == 0x00
|| Encoding.ASCII.GetString(sig) is "OTTO" or "ttcf" or "true";
} Try / catch
try { glyphTypeface = new GlyphTypeface(fontUri); }
catch (System.IO.FileFormatException ex)
{
log.Warn($"Font file {fontUri} is not a usable font face", ex);
glyphTypeface = new GlyphTypeface(fallbackFontUri);
} Prevention
- Never point GlyphTypeface at .compositeFont files; resolve them to actual .ttf/.otf entries
- Verify font file signature bytes before loading
- Ensure font resources are embedded as Build Action: Resource and referenced via pack URIs
- Checksum bundled fonts in CI to catch corrupted packaging
When it happens
Trigger: Calling new GlyphTypeface(uri) or ISupportInitialize EndInit with a URI pointing to a composite font file, a corrupted/truncated font file, a non-font file with a font extension, or a font format DirectWrite cannot parse.
Common situations: Deploying an app where the font file got corrupted or replaced during build/packaging; pointing GlyphTypeface at a .compositeFont definition (which is a WPF-level reference list, not a binary font); shipping a placeholder or zero-byte file; passing a resource path that resolves to an HTML error page or manifest instead of a font.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- SR.UriNotAbsolute
- styleSimulations
- Count must be 1 when CommitPolicies is set to…
- Document does not contain a package.
- Document does not contain any rights management-protected…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b4198346547b5d3b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphTypeface.cs:145
&& styleSimulations != StyleSimulations.ItalicSimulation
&& styleSimulations != StyleSimulations.BoldSimulation
&& styleSimulations != StyleSimulations.BoldItalicSimulation)
{
throw new InvalidEnumArgumentException("styleSimulations", (int)styleSimulations, typeof(StyleSimulations));
}
_styleSimulations = styleSimulations;
MS.Internal.Text.TextInterface.FontCollection fontCollection = DWriteFactory.GetFontCollectionFromFile(fontSourceUri);
using (MS.Internal.Text.TextInterface.FontFace fontFaceDWrite = DWriteFactory.Instance.CreateFontFace(fontSourceUri,
(uint)faceIndex,
(MS.Internal.Text.TextInterface.FontSimulations)styleSimulations))
{
// This is the same behavior as 3.*. If we pass, for example, a path to a composite font file then a
// FileFormatException will be thrown!
if (fontFaceDWrite == null)
{
throw new System.IO.FileFormatException(typefaceSource);
}
_font = fontCollection.GetFontFromFontFace(fontFaceDWrite);
}
_fontFace = new FontFaceLayoutInfo(_font);
_fontSource = new FontSource(fontSourceUri);
_initializationState = InitializationState.IsInitialized; // fully initialized
}
#endregion Constructors
//------------------------------------------------------
//
// Public Methods
//View on GitHub (pinned to 81131a70a4)