Opening and Saving a Presentation in C# Throws a KeyNotFoundException

Hi Team,

A simple open and save action of the attached pptm throws the following exception:

System.Collections.Generic.KeyNotFoundException: The given key ‘Cambria Math’ was not present in the dictionary.
at System.Collections.Generic.Dictionary2.get_Item(TKey key) at ..(String ) at .(Graphics ,  ,  ) at .(IList1 ,  ,  )
at .e( )
at e.( )
at e.( )
at e.( )
at .( , & , MathJustification ,  , Single )
at .( , MathJustification ,  , Single )
at .( , Boolean , Single )
at .( , Boolean , Char[] )
at .()
at .( ,  )
at …ctor(TextFrame ,  ,  )
at …ctor( , Int32 , Int32 )
at .( )
at .( )
at e.()
at e…ctor(TextFrame ,  , IBaseSlide ,  , [] )
at .( ,  )
at .( , Single , Single ,  )
at .( , & , RectangleF& ,  )
at .( , ShapeFrame& , RectangleF& ,  )
at .( )
at .(IAutoShape ,  ,  , e )
at .(AutoShape ,  ,  , e )
at .(IShape ,  ,  , e )
at .(IGroupShape ,  ,  , e )
at .(IBaseSlide ,  ,  )
at .(ISlide )
at .(e , ISlide ,  )
at .(Presentation , ee , IPptxOptions , InterruptionToken )
at .(Presentation , Stream , ee , IPptxOptions , InterruptionToken )
at Aspose.Slides.Presentation.(Stream , ee , IPptxOptions )
at Aspose.Slides.Presentation.Save(Stream stream, SaveFormat format, ISaveOptions options)
at Aspose.Slides.Presentation.Save(String fname, SaveFormat format)

the code is question is

static private readonly Dictionary<LoadFormat, SaveFormat> LoadFormatToSaveFormat = new Dictionary<LoadFormat, SaveFormat>
{
    {LoadFormat.Ppt, SaveFormat.Ppt},
    {LoadFormat.Ppt95, SaveFormat.Ppt},
    {LoadFormat.Pptx, SaveFormat.Pptx},
    {LoadFormat.Pptm, SaveFormat.Pptm},
    {LoadFormat.Pot, SaveFormat.Pot},
    {LoadFormat.Potx, SaveFormat.Potx},
    {LoadFormat.Potm, SaveFormat.Potm},
    {LoadFormat.Pps, SaveFormat.Pps},
    {LoadFormat.Ppsx, SaveFormat.Ppsx},
    {LoadFormat.Ppsm, SaveFormat.Ppsm},
    {LoadFormat.Odp, SaveFormat.Odp},
    {LoadFormat.Otp, SaveFormat.Otp}
};

var presentationInfo = PresentationFactory.Instance.GetPresentationInfo(inputPath);
var presentation = new Presentation(inputPath);
presentation.Save(outputPath, LoadFormatToSaveFormat[presentationInfo.LoadFormat]);

This exception happens despite ‘Cambria Math’ font being installed and available in the system.

Platfrom: linux
Package: Aspose.Slides.NET6.CrossPlatform Version=“25.10.0”

cambria_math_font_pptm.zip (1.3 MB)

@zpopswat

Summary
KeyNotFoundException: 'Cambria Math' occurs because Aspose.Slides cannot locate the Cambria Math font on the Linux host. The presentation (PPTM) contains Math objects that were created with this proprietary font, and when the font is missing the library throws the exception while loading or saving the file.

Why it happens

Reason Explanation
Cambria Math is not installed on Linux Linux distributions do not include the proprietary Cambria Math font. Installing the generic “Microsoft core fonts” package does not add the Math variant.
Aspose.Slides relies on the system font configuration The library queries the system’s font‑config cache to build a list of available fonts. If Cambria Math is not registered, the internal dictionary lacks an entry, leading to the KeyNotFoundException.
The PPTM contains Math objects Equations in the file reference the Cambria Math font. When the presentation is processed, the library needs the exact font (or a suitable substitute).
No font substitution is defined By default Aspose.Slides does not fall back to another font for Cambria Math. Without explicit substitution the missing‑font case is treated as an error.

What to do next

  1. Make the font available to the Linux system
  • Copy Cambria Math.ttf (or CambriaMath.ttf) from a Windows machine to a directory that is scanned by fontconfig, e.g. /usr/share/fonts/truetype/microsoft/.
  • Refresh the font cache: fc-cache -f -v.
  • (Optional) Verify the font is visible: fc-list | grep -i "Cambria Math".
  1. Tell Aspose.Slides where to look for fonts
using Aspose.Slides;
using Aspose.Slides.Export;
using Aspose.Slides.Fonts; // namespace for FontSettings

// 1️⃣ Create a FontSettings instance and point it to the folder that contains Cambria Math
var fontSettings = new FontSettings();
fontSettings.SetDefaultFontFolder("/usr/share/fonts/truetype/microsoft/", true);

// 2️⃣ (Optional) Define a substitution in case the font is still not found
fontSettings.Substitution.AddSubstitutes("Cambria Math",
new[] { "Arial Unicode MS", "DejaVu Math TeX Gyre" });

// 3️⃣ Load the presentation, passing the FontSettings via LoadOptions (available in recent versions)
var loadOptions = new LoadOptions
{
LoadFormat = LoadFormat.Pptm,
FontsManager = fontSettings // if the property exists; otherwise assign after loading
};

var presentation = new Presentation("input.pptm", loadOptions);
// If LoadOptions.FontsManager is not supported, use:
// var presentation = new Presentation("input.pptm");
// presentation.FontsManager = fontSettings;

// 4️⃣ Save the presentation
presentation.Save("output.pptm", SaveFormat.Pptm);
  1. Confirm that the font is recognized by Aspose.Slides (debug step)
var available = fontSettings.GetAvailableFonts();
bool hasCambria = available.Any(f =>
f.FontFamilyName.Equals("Cambria Math", StringComparison.OrdinalIgnoreCase));
Console.WriteLine($"Cambria Math available to Aspose.Slides: {hasCambria}");

If the output is false, double‑check the file path and re‑run fc-cache.

  1. If you cannot distribute the proprietary font
  • Choose a free alternative (e.g., DejaVu Math TeX Gyre) and configure it as a substitution as shown in step 2.
  • Alternatively, remove Math objects from the presentation before saving, but be aware that this changes the visual content.
  1. Re‑run your original workflow
    The dictionary you built for LoadFormat → SaveFormat is unrelated to the exception; after the font is made available (or a substitution is defined) the presentation should load and save without the KeyNotFoundException.

If the problem persists after completing the steps above, capture the list returned by fontSettings.GetAvailableFonts() and provide it for further internal analysis.

:warning: I could not fully verify this explanation against the retrieved sources. Please double-check the behaviour in your environment and confirm the exact SDK/version.

Not sure about the code in the previous post.

FontSettings

doesn’t even seem to be part of Aspose.Slides.

Not sure how to list available fonts using Aspose.Slides classes/methods.

Anyways, ‘Cambria Math’ is installed in the system, as the command confirms:

[root@s8sm39786d]# fc-list | grep -i “Cambria Math”.
/root/.fonts/cambria.ttc: Cambria Math:style=Regular

@zpopswat,
Thank you for contacting free support. We are sorry you encountered this problem. I need some time to investigate the issue. I will get back to you as soon as possible.

@zpopswat,
I was able to reproduce the error you described only when the Cambria Math was not installed on the operating system. I used the following Dockerfile:

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build

WORKDIR /source
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -o /app

FROM mcr.microsoft.com/dotnet/runtime:9.0

RUN apt-get update && apt-get install -y \
 libfontconfig1 \
 libfreetype6

WORKDIR /app
COPY --from=build /app .

ENTRYPOINT ["./NetcoreApp"]

However, after I installed the font, the error disappeared.

# Install the Cambria Math font.
RUN apt-get update && apt-get install -y \
    fontconfig \
 && rm -rf /var/lib/apt/lists/*
COPY cambria.ttc /usr/local/share/fonts/truetype/microsoft/cambria.ttc
RUN fc-cache -f -v

If the issue persists, please provide the following additional information:

  • The name and version of the operating system where the code was executed.
  • The .NET target platform used in your application project.
  • Any additional steps or details that help reproduce the error.

@andrey.potapov we use a custom container based on oraclelinux:8 and
<TargetFramework>net8.0</TargetFramework>

However taking your example above I still can reproduce the issue with a minimal container FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build

  1. build a minimal container FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
  2. run and instance and enter using bash
  3. create, build and run console app
    • dotnet new console -n cambriatest
    • cd cambriatest
    • dotnet add package Aspose.Slides.NET6.CrossPlatform --version 25.10.0
    • dotnet build && dotnet run

use this code

using Aspose.Slides;
using Aspose.Slides.Export;
Console.WriteLine("Hello, World!");
var presentation = new Presentation("my.pptm");
presentation.Save("out.pptm", SaveFormat.Pptm);

the exception appears

Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key ‘Cambria Math’ was not present in the dictionary.

copy cambria.ttx into /root/.fonts and run fc-cache -v -r

root@ddd75ecd4828:/apps/cambriatest# fc-cache -v -r
Font directories:
/root/.local/share/fonts
/usr/local/share/fonts
/usr/share/fonts
/root/.fonts
/usr/share/fonts/truetype
/usr/share/fonts/truetype/dejavu
/root/.local/share/fonts: skipping, no such directory
/usr/local/share/fonts: caching, new cache contents: 0 fonts, 0 dirs
/usr/share/fonts: caching, new cache contents: 0 fonts, 1 dirs
/usr/share/fonts/truetype: caching, new cache contents: 0 fonts, 1 dirs
/usr/share/fonts/truetype/dejavu: caching, new cache contents: 6 fonts, 0 dirs
/root/.fonts: caching, new cache contents: 2 fonts, 0 dirs
/usr/share/fonts/truetype: skipping, looped directory detected
/usr/share/fonts/truetype/dejavu: skipping, looped directory detected
/var/cache/fontconfig: cleaning cache directory
/root/.cache/fontconfig: not cleaning non-existent cache directory
/root/.fontconfig: not cleaning non-existent cache directory
fc-cache: succeeded

run fc-list | grep -i "Cambria"

root@ddd75ecd4828:/apps/cambriatest# fc-list | grep -i “Cambria”
/root/.fonts/cambria.ttc: Cambria:style=Regular
/root/.fonts/cambria.ttc: Cambria Math:style=Regular

the Cambria fonts are cached as expected.

Clean, rebuild and rerun the application, and the exception still appears

I see the difference in where you and I put our font file. However me putting the file into /root/.fonts should not make any difference in terms of fc-cache being able to discover and cache it.

@zpopswat,
I used the following Dockerfile for oraclelinux:8 + .NET 8 environment:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build

WORKDIR /source
COPY *.csproj ./
RUN dotnet restore

COPY . ./
RUN dotnet publish -c Release -r linux-x64 --self-contained true -o /app

FROM oraclelinux:8

RUN yum -y install \
        libicu \
        fontconfig \
        freetype \
    && yum clean all \
    && rm -rf /var/cache/yum

# Install the Cambria font.
RUN mkdir -p /usr/share/fonts/truetype/microsoft
COPY cambria.ttc /usr/share/fonts/truetype/microsoft/cambria.ttc
RUN chmod 644 /usr/share/fonts/truetype/microsoft/cambria.ttc
RUN fc-cache -f -v

WORKDIR /app
COPY --from=build /app .

ENTRYPOINT ["./NetcoreApp"]

The error does not appear. I hope this will help you.

I can confirm that putting the font file at /usr/share/fonts/truetype/microsoft/cambria.ttc resolves this issue. The exception does not happen any more.
Thank you for your support!

@zpopswat,
We are glad to know that the issue has been resolved. Thank you for using Aspose.Slides.