QL-Win/QuickLook · error · InvalidDataException

AppxMetadata/AppxBundleManifest.xml not found

Error message

AppxMetadata/AppxBundleManifest.xml not found

What it means

Thrown by AppxBundleReader.Open when the zip archive does not contain an entry named 'AppxMetadata/AppxBundleManifest.xml'. This entry is mandatory in every valid .appxbundle; its absence means the file is not an app bundle, is corrupt, or has an unexpected structure. The error is an InvalidDataException.

Solutions

  1. Confirm the file is actually an .appxbundle (look for AppxMetadata/AppxBundleManifest.xml inside the zip) before constructing AppxBundleReader.
  2. If the file is a single .appx/.msix package, use AppxReader instead.
  3. List zip entries and check for the manifest path; if missing, surface a clear 'not an app bundle' message.
  4. Handle InvalidDataException and fall back to trying AppxReader.

Example fix

// before
var reader = new AppxBundleReader(path);

// after
using var zip = new ICSharpCode.SharpZipLib.Zip.ZipFile(path);
bool isBundle = zip.GetEntry("AppxMetadata/AppxBundleManifest.xml") != null;
zip.Close();
if (!isBundle)
    throw new InvalidDataException($"{path} is not an .appxbundle (manifest missing).");
var reader = new AppxBundleReader(path);
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the zip contains the bundle manifest before constructing AppxBundleReader.
public static bool IsAppxBundle(string path)
{
    try
    {
        using var zip = new ICSharpCode.SharpZipLib.Zip.ZipFile(path);
        return zip.GetEntry("AppxMetadata/AppxBundleManifest.xml") != null;
    }
    catch { return false; }
}

Try / catch

try { var reader = new AppxBundleReader(path); }
catch (InvalidDataException ex) when (ex.Message.Contains("AppxBundleManifest"))
{
    // Not an .appxbundle; try AppxReader for a single .appx package instead.
}

Prevention

When it happens

Trigger: Constructing new AppxBundleReader(stream) or new AppxBundleReader(path) on a file that is a plain .appx (not a bundle), a .msix, a zip with unrelated contents, or a corrupt/truncated .appxbundle whose manifest entry is missing or at a different path.

Common situations: Passing an .appx (single package) to AppxBundleReader instead of AppxReader; passing an .msix bundle whose manifest path differs; a partially downloaded/corrupt bundle; a repackaged zip that lost the AppxMetadata directory.

Related errors


AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13). Data as JSON: /api/errors/6bcfe0fe3a7c82a6. Report an issue: GitHub.

Appendix: source

Thrown at QuickLook.Plugin/QuickLook.Plugin.AppViewer/PackageParsers/Appx/AppxBundleReader.cs:71

    public AppxBundleReader(string path)
    {
        Open(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read));
    }

    public void Dispose()
    {
        appxReader?.Dispose();
        appxReader = null;
        zip?.Close();
        zip = null;
    }

    private void Open(Stream stream)
    {
        zip = new ZipFile(stream);
        ZipEntry entry = zip.GetEntry("AppxMetadata/AppxBundleManifest.xml")
           ?? throw new InvalidDataException("AppxMetadata/AppxBundleManifest.xml not found");

        XmlDocument xml = new() { XmlResolver = null };
        xml.Load(zip.GetInputStream(entry));

        XmlElement bundleNode = xml.DocumentElement;

        // Identity
        {
            XmlElement identityNode = bundleNode["Identity"];

            if (identityNode != null)
            {
                name = identityNode.Attributes["Name"]?.Value;
                version = identityNode.Attributes["Version"]?.Value;
                publisher = identityNode.Attributes["Publisher"]?.Value;

                Match m = Regex.Match(Publisher, @"CN=([^,]*),?");
                if (m.Success) publisher = m.Groups[1].Value;

View on GitHub (pinned to cb5d9c429c)