stride3d/stride · error · InvalidOperationException

Failed to initialize msdfgen context

Error message

Failed to initialize msdfgen context

What it means

After FreeType initializes, Import creates the msdfgen processing context with msdfgenContextCreate. If it returns IntPtr.Zero the native msdfgen library failed to create its context; the importer frees the FreeType library and throws this InvalidOperationException. Without this context no multi-channel signed distance fields can be generated.

Solutions

  1. Ensure the stride_msdfgen native library for the target platform is present and loadable (check loader errors around the NativeLibraryHelper preload).
  2. Reinstall or rebuild Stride's native dependencies so managed and native versions match.
  3. Check available memory on the build machine; context creation can fail on allocation failure.
  4. Upgrade to a Stride version where the msdfgen platform issue is fixed if you are on an affected platform.
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the native msdfgen dependency is present before import
NativeLibraryHelper.PreloadLibrary("stride_msdfgen", typeof(SignedDistanceFieldFontImporter));
// optionally probe free memory; context creation can fail on allocation failure
if (GC.GetTotalMemory(forceFullCollection: false) > threshold) GC.Collect();

Type guard

bool MsdfgenAvailable() => NativeLibrary.TryLoad("stride_msdfgen", out _);

Try / catch

try
{
    importer.Import(fontSource, characters, options);
}
catch (InvalidOperationException ex) when (ex.Message == "Failed to initialize msdfgen context")
{
    logger.LogError(ex, "msdfgen context creation failed. Verify stride_msdfgen native library presence/version and available memory.");
    throw; // environmental failure — fix native deps or memory, then rerun
}

Prevention

When it happens

Trigger: Calling SignedDistanceFieldFontImporter.Import when the native msdfgen context creation returns a null pointer — e.g. stride_msdfgen failed to preload correctly, native memory allocation failure, or a broken/mismatched msdfgen binary.

Common situations: Missing stride_msdfgen native dependency in the output folder; an msdfgen build incompatible with the target platform; out-of-memory on constrained build agents; mixing Stride versions where native libs and managed assemblies disagree.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/23841b87972a6e2a. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Assets/SpriteFont/Compiler/SignedDistanceFieldFontImporter.cs:55

        /// <inheritdoc/>
        public void Import(SpriteFontAsset options, List<char> characters)
        {
            fontSource = options.FontSource.GetFontPath();
            if (string.IsNullOrEmpty(fontSource))
                return;

            NativeLibraryHelper.PreloadLibrary("freetype", typeof(SignedDistanceFieldFontImporter));
            NativeLibraryHelper.PreloadLibrary("stride_msdfgen", typeof(SignedDistanceFieldFontImporter));

            int err = FreeTypeNative.FT_Init_FreeType(out var library);
            if (err != 0)
                throw new InvalidOperationException($"Failed to initialize FreeType library (error {err})");

            msdfgenContext = MsdfgenNative.msdfgenContextCreate();
            if (msdfgenContext == IntPtr.Zero)
            {
                FreeTypeNative.FT_Done_FreeType(library);
                throw new InvalidOperationException("Failed to initialize msdfgen context");
            }

            msdfgenFont = MsdfgenNative.msdfgenLoadFont(msdfgenContext, fontSource);
            if (msdfgenFont == IntPtr.Zero)
            {
                MsdfgenNative.msdfgenContextDestroy(msdfgenContext);
                msdfgenContext = IntPtr.Zero;
                FreeTypeNative.FT_Done_FreeType(library);
                throw new AssetException($"Failed to load font '{fontSource}' into msdfgen.");
            }

            try
            {
                var fontData = File.ReadAllBytes(fontSource);
                var handle = GCHandle.Alloc(fontData, GCHandleType.Pinned);

                try
                {

View on GitHub (pinned to 96fad776d2)