iOfficeAI/OfficeCLI · error · InvalidOperationException

word_not_authentic

Error message

word_not_authentic: {name}

What it means

Thrown by DocxToPdf after CoCreateInstance instantiates CLSID {000209FF-0000-0000-C000-000000000046} (Word.Application) and queries its Name property. If the name does not contain 'Microsoft Word' (case-insensitive), the backend refuses to proceed, because a different application or a non-Word COM server registered under that CLSID would silently produce garbage or hang. This is a security/authenticity guard: it prevents the PDF backend from driving an unexpected or spoofed COM server that happens to occupy Word's class ID.

Solutions

  1. Run 'winword.exe' manually to confirm Word launches and reports itself as 'Microsoft Word' in its title bar.
  2. Repair the Office installation: Settings > Apps > Microsoft 365/Office > Modify > Online Repair.
  3. If the Name property returns a localized or version-specific string (e.g. 'Microsoft Word 2016'), the Contains check already handles that — if it still fails, inspect the exact Name value returned and report it.
  4. On a server, install Word via a volume-license Office build rather than click-to-run, which is known to leave registration stubs.
Defensive patterns

Strategy: validation

Validate before calling

// Check that Word reports itself correctly before relying on the backend
// This mirrors the internal check; if it fails, PDF conversion is unavailable
var clsid = new Guid("000209FF-0000-0000-C000-000000000046");
var iid = new Guid("00020400-0000-0000-C000-000000000046");
try
{
    WordPdfBackend.CoCreateInstance(ref clsid, IntPtr.Zero, 4, ref iid, out var word);
    try
    {
        var name = (string)WordPdfBackend.DispGet(word, "Name");
        if (!name.Contains("Microsoft Word", StringComparison.OrdinalIgnoreCase))
            throw new PlatformNotSupportedException($"Word authenticity check failed: {name}");
    }
    finally { Marshal.Release(word); }
}
catch { /* Word not available or not authentic */ }

Try / catch

try
{
    var pdf = WordPdfBackend.DocxToPdf(docxPath);
}
catch (InvalidOperationException ex) when (ex.Message.StartsWith("word_not_authentic"))
{
    // The COM server under Word's CLSID is not genuine Microsoft Word
    logger.LogError("Word authenticity check failed: {Detail}", ex.Message);
    throw new PlatformNotSupportedException(
        "PDF conversion requires genuine Microsoft Word to be installed.");
}

Prevention

When it happens

Trigger: The CLSID {000209FF-...} is registered but resolves to something other than Microsoft Word — e.g. an Outlook MAPI or Office runtime stub on machines with only a partial Office install, a third-party application that hijacked the CLSID, a Wine/Corosiva-CrossOver environment where the COM server reports a different Name, or a registry corruption where Word is partially uninstalled but the CLSID entry remains.

Common situations: Server with Office Online Server or Office runtime redistributable but no desktop Word; a machine with only Microsoft 365 click-to-run streaming stub where Word is not fully downloaded yet; WINE/CrossOver where the COM bridge reports a Wine-specific name; a damaged Office install after a failed update.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/8b0eec1af96f9b30. Report an issue: GitHub.

Appendix: source

Thrown at src/officecli/Core/WordPdfBackend.cs:461

                int srcStride = p.w * 4;
                for (int row = 0; row < p.h; row++)
                    Array.Copy(p.pixels, row * srcStride, target, (y0 + row) * targetStride + x0 * 4, srcStride);
            }
            return EncodeBgraToPng(factory, target, W, H);
        }
        finally { Marshal.Release(factory); }
    }

    static string DocxToPdf(string docx)
    {
        var pdf = Path.Combine(Path.GetTempPath(), $"_w_{Guid.NewGuid():N}.pdf");
        var clsid = G_Word; var iid = G_IDispatch;
        CoCreateInstance(ref clsid, IntPtr.Zero, 4, ref iid, out var word);
        try
        {
            var name = (string?)DispGet(word, "Name") ?? "";
            if (!name.Contains("Microsoft Word", StringComparison.OrdinalIgnoreCase))
                throw new InvalidOperationException("word_not_authentic: " + name);

            DispSet(word, "Visible", false);
            DispSet(word, "DisplayAlerts", 0);
            try { DispSet(word, "AutomationSecurity", 3); } catch { }

            var docs = (IntPtr)DispGet(word, "Documents")!;
            try
            {
                var doc = (IntPtr)DispMethod(docs, "Open", docx, MISSING, true, false)!;
                try { DispMethod(doc, "SaveAs2", pdf, 17); }
                finally { try { DispMethod(doc, "Close", false); } catch { } Marshal.Release(doc); }
            }
            finally { Marshal.Release(docs); }
        }
        finally
        {
            try { DispMethod(word, "Quit"); } catch { }
            Marshal.Release(word);

View on GitHub (pinned to 1ced45e900)