{"id":2944,"library":"extract-msg","title":"extract-msg: Outlook MSG File Extractor","description":"extract-msg is a Python library designed to parse and extract emails and their attachments from Microsoft Outlook's proprietary .msg files. It supports various MSG file formats, including embedded messages and complex structures, and can handle different encodings. The library is actively maintained with frequent minor and patch releases, currently at version 0.55.0.","status":"active","version":"0.55.0","language":"python","source_language":"en","source_url":"https://github.com/TeamMsgExtractor/msg-extractor","tags":["email","outlook","msg","parser","attachments","ole","microsoft"],"install":[{"cmd":"pip install extract-msg","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"symbol":"Message","correct":"from extract_msg import Message"}],"quickstart":{"code":"import os\nfrom extract_msg import Message\n\n# Create a dummy .msg file for demonstration\n# In a real scenario, you'd replace 'example.msg' with your actual file path\n# This part is just to make the example runnable without an actual .msg file present initially\n# A real .msg file structure is complex and cannot be simply created like this.\n# Assume 'example.msg' exists and contains an Outlook message.\n# For testing, you might use a pre-existing sample .msg file.\n\nmsg_file_path = 'example.msg'\nif not os.path.exists(msg_file_path):\n    # This part would typically be replaced by pointing to an actual .msg file.\n    # For a truly runnable example, one would need a sample .msg file.\n    print(f\"Please create a file named '{msg_file_path}' containing a valid Outlook .msg email to run this example.\")\n    print(\"Using a placeholder for demonstration purposes.\")\n    # Exit or handle gracefully if no .msg file is found for testing.\n    # For this example, we'll proceed assuming it will fail, or a real file exists.\n\n\ntry:\n    with Message(msg_file_path) as msg:\n        print(f\"Subject: {msg.subject}\")\n        print(f\"Sender: {msg.sender}\")\n        print(f\"Date: {msg.date}\")\n        print(f\"Body (plain text):\\n{msg.body[:200]}...\") # Print first 200 chars\n\n        if msg.attachments:\n            print(f\"\\nAttachments found: {len(msg.attachments)}\")\n            output_dir = 'attachments_output'\n            os.makedirs(output_dir, exist_ok=True)\n            for attachment in msg.attachments:\n                filename = attachment.longFilename or attachment.shortFilename\n                if filename:\n                    try:\n                        attachment.save(customPath=output_dir, raw=False)\n                        print(f\"  Saved attachment: {filename}\")\n                    except Exception as e:\n                        print(f\"  Error saving attachment {filename}: {e}\")\n        else:\n            print(\"\\nNo attachments.\")\nexcept FileNotFoundError:\n    print(f\"Error: The file '{msg_file_path}' was not found. Please ensure it exists.\")\nexcept Exception as e:\n    print(f\"An error occurred while processing the MSG file: {e}\")\n","lang":"python","description":"This quickstart demonstrates how to open an MSG file, access its subject, sender, date, and body, and save any attached files. It uses a context manager (`with Message(...) as msg:`) to ensure proper resource handling."},"warnings":[{"fix":"Explicitly set `maxNameLength` in `attachment.save()` or `MessageBase.save()` methods if you require longer filenames, e.g., `attachment.save(maxNameLength=256)`.","message":"The default `maxNameLength` for filenames when saving attachments or message data has changed from 256 to 40 characters in version 0.55.0. If you relied on longer filenames by default, your saved files might now be truncated.","severity":"gotcha","affected_versions":">=0.55.0"},{"fix":"Adjust your HTML parsing logic to account for the change to plain HTML. If prettification is desired, you may need to apply a separate HTML prettifier (e.g., `BeautifulSoup`) after extraction.","message":"The prepared HTML output (e.g., via `msg.htmlBody`) changed in version 0.54.0 to use plainly encoded HTML instead of a prettified format. If your application parsed or relied on the structure of the prettified HTML, this change may affect you.","severity":"breaking","affected_versions":">=0.54.0"},{"fix":"Always use the `with Message(...) as msg:` context manager pattern to ensure files are properly closed and resources are released, even if the file is a plain OLE file. If you are manually handling `MSGFile` objects, ensure `close()` is called.","message":"Prior to version 0.55.0, if `openMsg()` or `Message` (when opening specific OLE files that weren't standard MSG) was used without a context manager (`with...as`), the underlying OLE file handle might not be closed, leading to resource leaks. While `openMsg()` was fixed internally in 0.55.0, it's a good practice to always use context managers.","severity":"gotcha","affected_versions":"<0.55.0 (for `openMsg`), all versions (for best practice)"},{"fix":"Ensure your environment's locale settings are appropriate for the expected encodings. Report specific malformed files to the library maintainers if issues persist after updating to the latest version. The library continuously improves its handling of diverse encodings.","message":"Encoding issues, particularly with child/embedded MSG files and their interaction with the parent's encoding, have been a source of bugs (e.g., fixed in v0.54.1, v0.52.0). While fixes are implemented, be aware that complex nested MSG structures or malformed files can still present encoding challenges.","severity":"gotcha","affected_versions":"All versions (potential for edge cases with malformed files)"}],"env_vars":null,"search_vec":"'0.55.0':62 'activ':51 'attach':23,67 'complex':41 'current':59 'design':15 'differ':46 'email':20,63 'embed':38 'encod':47 'extract':2,9,19 'extract-msg':1,8 'extractor':7 'file':6,30,35 'format':36 'frequent':54 'handl':45 'includ':37 'librari':14,49 'maintain':52 'messag':39 'microsoft':25,69 'minor':55 'msg':3,5,10,29,34,65 'ole':68 'outlook':4,26,64 'pars':17 'parser':66 'patch':57 'proprietari':28 'python':13 'releas':58 'structur':42 'support':32 'various':33 'version':61","created_at":"2026-04-11T09:14:17.785365+00:00","updated_at":"2026-04-16T14:53:49.372665+00:00","problems":[{"fix":"Install the library using pip: `pip install extract-msg`","cause":"The `extract-msg` library has not been installed or is not accessible in the current Python environment.","error":"ModuleNotFoundError: No module named 'extract_msg'"},{"fix":"Use the `openMsg` function instead: `import extract_msg; msg = extract_msg.openMsg('path/to/your/file.msg')`","cause":"This error usually occurs when attempting to call `extract_msg.Message()` directly, which is often an internal class, or due to API changes between versions. The recommended public API for opening MSG files is `extract_msg.openMsg()`.","error":"AttributeError: module 'extract_msg' has no attribute 'Message'"},{"fix":"When opening the message, specify the correct encoding if known, or try common encodings like 'latin-1' or 'cp1252'. You can also use error handling to ignore problematic characters: `msg = extract_msg.openMsg('path/to/file.msg', overrideEncoding='cp1252', errors='ignore')` or `msg = extract_msg.openMsg('path/to/file.msg', errors='replace')`","cause":"This error arises when `extract-msg` attempts to decode text from an MSG file using an incorrect character encoding (often the system's default, like 'charmap' or 'utf-8') that doesn't match the file's actual encoding. MSG files can contain various encodings.","error":"UnicodeDecodeError: 'charmap' codec can't decode byte 0x... in position ...: character maps to <undefined>"},{"fix":"While direct support for all container types might not be implemented, you can handle this by wrapping the attachment extraction in a try-except block to skip unsupported attachments: `for attachment in msg.attachments: try: attachment.save() except NotImplementedError: print(f'Skipping unsupported attachment: {attachment.longFilename}')`","cause":"This specific error indicates that the library encountered an attachment type within the MSG file that it does not currently support for extraction (e.g., certain OLE objects or non-MSG/EML container types).","error":"NotImplementedError: Current version of extract_msg does not support extraction of containers that are not embedded msg files."}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.56.1","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/TeamMsgExtractor/msg-extractor","docs":null,"changelog":null,"pypi":"https://pypi.org/project/extract-msg/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["data","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-28","next_check":"2026-07-28","install_tag":null}}