dotnet / dotnet/Open-XML-SDK

WordprocessingDocument.Open returns null MainDocumentPart when [Content_Types].xml omits Default Extension="rels"

Open
#2,091 0 comments 0 reactions 1 assignee Claimed by @mkaszewiak View on GitHub
Dominant language
C#
Stars
4.6k
Forks
605
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**
When opening a .docx file whose [Content_Types].xml is missing the required entry, WordprocessingDocument.MainDocumentPart is null. Any code
that dereferences it without a null check then throws NullReferenceException.

This is a known real-world OPC spec deviation (ECMA-376 Part 2 §10.1.2) produced by a number of OOXML generators. Word Desktop and other readers recover silently. The SDK does not.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**To Reproduce**
```
[Fact]
public void Open_MissingRelsContentType_MainDocumentPartIsNotNull()
{
var stream = new MemoryStream();
using (var zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
{
Write(zip, "[Content_Types].xml", """





""");
Write(zip, "_rels/.rels", """




""");
Write(zip, "word/document.xml", """




""");
}

stream.Position = 0;
using var doc = WordprocessingDocument.Open(stream, isEditable: false);

Assert.NotNull(doc.MainDocumentPart); // fails — returns null
}

static void Write(ZipArchive zip, string name, string content)
{
using var w = new StreamWriter(zip.CreateEntry(name).Open());
w.Write(content);
}
```

**Observed behavior**
doc.MainDocumentPart is null.

**Expected behavior**
MainDocumentPart should be non-null. The Default Extension="rels" entry is required by the OPC spec but is widely omitted in practice. Word Desktop and other readers tolerate this deviation; the SDK should too.

**Desktop (please complete the following information):**
- OS: Linux / macOS / Windows (reproducible on all)
- .NET Target: netstandard2.0, net6.0, net8.0 (all affected)
- DocumentFormat.OpenXml Version: latest main (9fe57e8)

**Root cause**

System.IO.Packaging is strict about content-type registration. When the Default Extension="rels" entry is absent from [Content_Types].xml, it cannot resolve .rels parts. As a result, PartRelationshipsFeature.LoadReferencedPartsAndRelationships
finds no internal relationships at the package level and MainDocumentPart comes back null.

**Additional context**
A fix is proposed in the linked PR. RepairRelsContentType() in StreamPackageFeature detects the missing entry before Package.Open and rebuilds the stream with it injected into [Content_Types].xml. All other ZIP entries are streamed verbatim.
The repair is a no-op for well-formed packages and falls back silently on any error so Package.Open can still produce its own diagnostics.
https://github.com/dotnet/Open-XML-SDK/pull/2090

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.