What Is an MSG File? An Outlook Message in One File, and How to Check One That Fails
An MSG file is one Outlook item in one file, and four readers disagreed on 15 of the 21 damaged copies we made of one. Jump to your question below, or work through it in order.
What Is an MSG File? One Outlook item in one file, and a second meaning in old games
Short answer
An MSG file is one Outlook item saved as a single file. It can store an email, a contact, an appointment or a task, with its recipients and attachments inside. FileInfo names it the Outlook Message Item File, and the same ending also names a Fallout game text file.
We read 41 MSG files from the Apache POI tests and damaged one of them in 21 ways. The file command named 40 of the 41 healthy MSG files. On the damaged copies the four readers that open MSG files disagreed on 15, and 12 kinds of damage came back byte for byte.
To open one, read the open steps. To check one, read the check steps. If your MSG file will not open, begin with the eight causes.
An MSG file is one Outlook item saved as a single file, with its recipients and attachments inside. The ending also names a Fallout game text file, so the first bytes show which one you have.
Picture a file called invoice.msg that a coworker saved from Outlook and another called 12.msg in the text folder of an old Fallout game. Both end in .msg. They share no format, no maker and no program.
FileInfo lists two MSG file types. The Outlook Message Item File comes from Microsoft and stores an email, a contact, an appointment, a meeting or a task with its attachments. The Fallout game message file comes from Bethesda Softworks and stores dialogue as plain text.
File-extensions.org lists four MSG records. They are a saved email message, a FoxPro FoxDoc message, an OS/2 help message and a SmartWare intro display file. It marks the FoxPro and OS/2 records obsolete.
We could test only the Outlook kind. The Apache POI project on GitHub ships 41 MSG files as test data, and we read all of them. The other meanings come from the pages we name, and we say so every time.
Where our MSG files come from
Apache POI is a Java project, and HSMF is its component for Outlook MSG files. The test data has 41 MSG files. They are 3,584 to 2,105,856 bytes long and 3,600,404 bytes in total, and the median is 29,696 bytes.
23 of the files are Unicode and 18 are ANSI. They cover 8 message classes, from mail to contacts, tasks, posts and sticky notes. Three of them are fuzz test files, which the project builds to break readers.
We damaged one MSG file, example_sent_unicode.msg, in 21 ways, and every copy changes one thing. We worked on Linux. We opened no MSG file in Outlook and had no sample of any other kind.
MSG file facts at a glance
| Property | Value |
|---|---|
| Meaning | Two main kinds. FileInfo lists the Outlook Message Item File and the Fallout game message file, and file-extensions.org lists four records. |
| Ending | .msg. Related endings are .eml for a message saved as text, .pst for an Outlook data file and .dat for winmail.dat. |
| First bytes |
Outlook MSG files start with d0 cf 11 e0 a1 b1 1a e1, the signature of a compound file. All 41 of ours do.
|
| Container | A compound file in version 3 with sectors of 512 bytes. Microsoft publishes the container as MS-CFB and the message layout as MS-OXMSG. |
| Streams | One stream for every property, named with a 4 digit tag and a 4 digit type. The type 001F is UTF 16 text and 001E is 8 bit text. |
| Sizes | Our 41 MSG files are 3,584 to 2,105,856 bytes long, and the median is 29,696 bytes. |
| Opens with | Outlook, per FileInfo, plus viewers like SeaMonkey and eM Client. We tested file, 7-Zip, olefile, extract-msg, msg_parser and our script on Linux. |
| Our tests | 41 healthy MSG files, 21 damaged copies and 12 repairs checked on every healthy MSG file where the damage changes bytes. |
Wrong page? A winmail.dat file is not an MSG file. See how the neighbors differ.
Which Kind of MSG File Do You Have? Four questions, and the first bytes answer the first one
Four questions name the kind of an MSG file. Start with the first 8 bytes, because every Outlook file we read starts with d0 cf 11 e0 a1 b1 1a e1.
Work down the figure and stop at the first yes. We tested only the first row. The others rest on the pages named in the rows, because we found no sample files for them.
The four kinds in detail
| Kind | Clue and source |
|---|---|
| Outlook message | The first 8 bytes are the compound file signature. FileInfo says it stores an Outlook item and its attachments, and that other programs with MAPI support can open or create it. Tested on 41 MSG files. |
| Fallout game text |
FileInfo says Fallout and Fallout 2 store dialogue as plain text, one message on every line, as three brace parts in a row, {###}, {soundfilename} and {Message text}. Source only.
|
| Saved mail | File-extensions.org lists a saved copy of an email from an email client and says an old DOS program, OzWin, used the ending. Source only. |
| Old program files | File-extensions.org lists a SmartWare intro display file meant for the program itself, plus a FoxPro FoxDoc message and an OS/2 help message that are both marked obsolete. Source only. |
Start with the first bytes
Open the MSG file in a hex viewer or use xxd -l 16. If the first 8 bytes read d0 cf 11 e0 a1 b1 1a e1, you have a compound file. If you see readable lines with braces, you have the Fallout text kind.
The same 8 bytes also start other compound files, like old Word and Excel files and installer packages. So they name the container and not the message. The file command goes further and printed CDFV2 Microsoft Outlook Message for 40 of our 41 MSG files.
The one exception is a fuzz test file. The file command printed Composite Document File V2 Document, Cannot read short stream for it, which means it saw the container and could not read inside.
text/english/game in it points to the game kind, per FileInfo.
Not sure your MSG file is an Outlook message at all? Check it with our script.
What Is Inside an MSG File? A container, a property stream and one stream for every value
An Outlook MSG file is a compound file with a header of 512 bytes, a directory, one property stream and one stream for every property. Our example file is 53,760 bytes long and has 137 entries.
We read MSG files because Microsoft publishes the layout and the Apache POI project ships examples, so every value can be checked. Two short commands show the first 16 bytes and name the type.
xxd -l 16 example_sent_unicode.msg
00000000: d0cf 11e0 a1b1 1ae1 0000 0000 0000 0000 ................
file -b example_sent_unicode.msg
CDFV2 Microsoft Outlook Message
file -b --mime-type example_sent_unicode.msg
application/vnd.ms-outlook
Bytes 0 to 7, d0 cf 11 e0 a1 b1 1a e1, are the signature of a compound file. The file command prints a longer name, CDFV2 Microsoft Outlook Message, so it reads more than the signature.
The MIME type line prints application/vnd.ms-outlook. We read the IANA registry on 29 October 2026 and found vnd.ms-tnef but no vnd.ms-outlook. Treat the type as a label that tools print and not as a registered standard.
The header, byte by byte
Bytes 24 and 25 give the minor version, 62, and bytes 26 and 27 give the major version, 3. Bytes 28 and 29, fe ff, mark low byte first order. Bytes 30 and 31 read 9, so a sector is 2 to the power of 9, or 512 bytes.
Bytes 44 to 47 give the count of FAT sectors, which is 1 here. Bytes 48 to 51 give the first directory sector, which is 2. Bytes 56 to 59 give the mini stream cutoff, 4,096. Streams below that size live in mini sectors of 64 bytes.
All 41 MSG files share the same version, sector size and cutoff. An MSG file with other values can be a version 4 file, which the container specification allows, or a damaged one.
The property stream and the counts
The stream named __properties_version1.0 in an MSG file starts with a header of 32 bytes. Bytes 8 to 11 give the next recipient ID and bytes 12 to 15 the next attachment ID. Bytes 16 to 19 give the recipient count and bytes 20 to 23 the attachment count.
In our example the stream is 912 bytes long, which is 32 plus 55 entries of 16 bytes. The counts read 8 and 1, and the MSG file has 8 recipient storages and 1 attachment storage. In all 41 MSG files the counts match the storages.
Every recipient and every attachment has its own storage with its own property stream. The attachment of our example keeps 16,174 bytes of data in one stream. A storage named __substg1.0_3701000D stores an embedded message when the attachment is itself an MSG file.
The value streams
A stream name in an MSG file has two parts after the prefix. The first 4 hex digits are the property tag and the last 4 are the type. In our example 0037001F is the subject in 72 bytes of UTF 16 text, and 001A001F is the message class, IPM.Note.
The body lives in 1000001F as text, in 10090102 as compressed RTF and in 10130102 as HTML. Our example has a text body of 660 bytes and an RTF body of 2,082 bytes, with no HTML stream. Plain text is in 37 of our 41 MSG files, RTF in 32 and HTML in 12.
The parts of an MSG file
| Part | What it stores and what we saw |
|---|---|
| Header | 512 bytes with the signature, the version 3, the sector size and the cutoff. The values were the same in all 41 MSG files. |
| Directory | A tree of storages and streams. Our example has 137 entries below the root. |
| Property stream | A header of 32 bytes and 16 bytes for every property. It repeats the recipient and attachment counts. |
| Value streams | One stream for every property, named by tag and type. 23 files use 001F text and 18 use 001E text. |
| Recipients |
One storage for every recipient. The largest file, lots-of-recipients, has 1,321.
|
| Attachments | One storage for every attachment. Our 41 MSG files contain 29 attachments in 13 files. |
What the sources say
Microsoft publishes the MSG layout as MS-OXMSG, and its revision table shows revision 18.0 from 20 May 2025. It says the format represents single email messages, appointments, contacts and tasks as files.
The container comes from a second document, MS-CFB on Microsoft Learn. We used both documents to name the fields, and every number on this page comes from our own files.
The text split matters. The specification says a flag named STORE_UNICODE_OK sets one kind of text for the entire file, so an MSG file cannot mix the two. None of our 41 MSG files does.
The map is small. Our script reads the header, the counts and the class. It does not read the values, so damage inside a value can pass it, as the 21 copies show.
What Did We Find in 41 MSG Files? Six readers, and three of them missed files
We read 41 MSG files with six readers. The file command named 40, 7-Zip opened 39, olefile and msg_parser opened all 41 and extract-msg opened 37. Our 22 line script passed all 41, with 3 warnings.
All 41 MSG files come from the Apache POI test data, so this is a study of one project and not a survey of every MSG file. Three are fuzz test files, and we opened none in Outlook.
Readers were file 5.45, 7-Zip 23.01, olefile 0.47, extract-msg 0.58.0, msg_parser 1.2.0 and our own script on Python 3.13, all on Linux. A reader passed an MSG file when it returned data without an error.
| Test | Result |
|---|---|
| The file command | Named 40 of 41 MSG files as CDFV2 Microsoft Outlook Message. For one fuzz test file it printed Composite Document File V2 Document, Cannot read short stream. |
| 7-Zip | Opened 39 files as a Compound archive and refused 2 fuzz test files. It lists the raw streams, so it shows the parts and not the message. |
| olefile | Opened all 41 MSG files and listed their streams. |
| extract-msg | Opened 37 files and failed on 4. Two are fuzz test files with an OleFileError. Two contain an embedded message and raised an AttributeError. |
| msg_parser | Opened all 41 MSG files. |
| Our script | Printed OK for 38 files and WARN for 3. The warnings are a tail that does not fill a sector, in one regular file and two fuzz test files. |
| Sizes | 3,584 to 2,105,856 bytes, with a median of 29,696 and a total of 3,600,404. |
| Recipients |
The largest file, lots-of-recipients, has 1,321 recipients and is 2,105,856 bytes long.
|
One container and 41 MSG files
Every MSG file starts with the compound file signature and uses version 3. All 41 use sectors of 512 bytes and a mini stream cutoff of 4,096. The number of FAT sectors is 1 in 35 MSG files, 2 in 3 files, 3 in 2 files and 33 in lots-of-recipients.
The counts in the property stream match the recipient and attachment storages in all 41 MSG files. 31 files are IPM.Note. The others are 3 Enterprise Vault shortcuts, 2 posts, a signed message, an appointment, a contact, a sticky note and a task.
Where readers split on healthy MSG files
The fuzz test files caused most of the splits. 7-Zip refused two of them, and extract-msg raised an OleFileError on the same two. The file command printed a different name for one of them. olefile and msg_parser opened all three.
Bodies and attachments
Plain text bodies are in 37 MSG files, RTF bodies in 32 and HTML bodies in 12, so many MSG files store more than one. 13 MSG files include attachments. The 29 attachments are 12 JPG pictures, 4 GIF pictures, 3 PNG pictures, a PDF, a DOC, a TXT and an EML file. Two more are embedded messages and 4 have no file name.
Read the study with care. It shows what six readers do with 41 MSG files from one project. Files from other programs and versions can differ, and we had no copy of Outlook to save our own.
What Happens When an MSG File Is Damaged? 21 broken copies, and the readers disagreed on 15
We damaged one MSG file in 21 ways. The four readers that open MSG files disagreed on 15 copies, and none of them matched the original on 10. Our script flagged 14, and 12 kinds of damage came back byte for byte.
The 21 copies of one MSG file come in three groups of 7. Group A changes the container header. Group B changes the length of the MSG file or how it was moved. Group C changes a count, a name or the data. Every copy changes one thing in example_sent_unicode.msg, which is 53,760 bytes long.
We asked three questions about every copy. What did every reader return, compared with the original? Did our script flag it? And did one command restore the original, checked by SHA-256 on every healthy MSG file where the damage changes bytes?
Four copies, four different answers
A2 changes the byte order mark of the MSG file. 7-Zip and extract-msg refused it, while olefile and msg_parser returned the original data. B1 cuts the last byte, and all four readers returned the original data.
C2 raises the recipient count by one. 7-Zip and olefile returned different data, while extract-msg and msg_parser matched the original. B7 cuts the last sector. 7-Zip and olefile returned different data, extract-msg refused it and msg_parser matched the original.
So no reader works as a judge of the others. A refusal warns you that something is wrong. A reader that returns different data says nothing, and that happened with at least one reader on 13 of the 21 copies.
The 14 copies our script flagged
A1 changes a byte of the signature and B6 removes the first byte, so neither starts with the signature. A2 and A4 change the byte order and the version, and the script names both together.
A3, A5, B5, C5 and C6 give one message, no property stream. In all five the container opens and the stream cannot be found, so the message points to the damage but not to its cause. B3 keeps only the 512 header bytes, and the script reports a directory error.
C2 and C3 raise a count by one, and the script reports the count that no longer matches the storages. B1 and B2 are cuts that leave a tail that does not fill a sector, so the script warns. A warning is weak, because one healthy MSG file had a 1 byte tail too.
The 7 copies our script passed
A6 sets the FAT sector count to 0 and A7 sets the mini stream cutoff to 0. B4 adds 512 zero bytes, and B7 cuts the last sector. C1 flips a bit, C4 zeroes the message class and C7 zeroes the second half. All seven copies of the MSG file keep a sound header and sound counts.
B4 is harmless, because all five readers returned the original data. A6 reads as the original in olefile, extract-msg and msg_parser, though 7-Zip refuses it. The other five differ in at least one reader. A pass means the container is sound and not that the message is intact. C4 even prints an empty class and still gets OK.
Repairs that worked
We wrote one command per kind of damage, 12 in all, and tested it on every healthy MSG file where the damage changes bytes. A hash matched the original for A1, A2, A3, A4, A6, A7, B6 and C5 on all 41 MSG files.
A5 worked on 31 of 31 files, B5 on 36 of 36 and C2 and C3 on 23 of 23. For C2 and C3 we counted only the files where the 32 byte header appears once, because a second copy of it would make the repair guess.
B5 mimics a text mode copy. Every repair fits a case where one thing is wrong. Damage in the wild changes many things at once, so a repair that works here can fail there.
What no command repaired
B1, B2, B3 and B7 cut the MSG file. C1 flips a bit, C4 and C7 zero data and C6 zeroes a FAT sector. Cut and zeroed data in an MSG file is gone, and no header brings it back. We tested no repair for those eight copies. B4 needs none.
Read the grid with care. Every copy changes one thing in one MSG file. Damage in the wild changes many things at once. We opened no copy in Outlook, and our repairs rely on rules that fit these 41 MSG files.
What Does Our Expert Say About MSG Files? A note from Neeraj Singh on trusting one reader
Compare two readers before you trust one. Our four readers disagreed on 15 of 21 damaged copies, so one reader that opens an MSG file proves little.
Expert insight
“An MSG file is a container, and four readers gave four different answers on the same damaged copy. In our test only one of 21 copies read the same in all five tools. Compare two readers, keep the original and write down its hash before you repair anything.”
Why one reader is not enough
A reader can return the wrong data without an error. Across our 21 copies, at least one reader did that on 13, and no message said so. A refusal at least warns you that something is wrong.
We had no copy of Outlook. If Outlook opens your MSG file, treat that as the best test. Use the readers on this page when it does not, and compare two of them before you act.
Copy your MSG file before you repair it. Work on the copy and keep the original untouched. Write down its SHA-256 hash first, so you can show later that the copy came back as it was.
How Do You Open an MSG File? Outlook first, then viewers that need no Outlook
Outlook opens an MSG file, per FileInfo, and so do SeaMonkey and eM Client. Several viewers need no Outlook. We opened none in Outlook and read the files with five tools on Linux.
The table lists what the sources name and what we tested. Rows with version numbers are tools we tested. Every other row rests on the page named in it, and we tested none of those.
| Program | What it does |
|---|---|
| Microsoft Outlook | FileInfo lists Microsoft Outlook 365 for Windows, and file-extensions.org lists Outlook for Mac. Microsoft made the format. We did not test it. |
| SeaMonkey and eM Client | FileInfo lists Mozilla SeaMonkey for Windows, Mac and Linux, and eM Client for Windows and Mac. We tested neither. |
| Viewers on the web | FileInfo lists Mailward, EML Tool and Mailactor EML Viewer for the web. We tested none, and a web viewer receives your MSG file. |
| Notepad and WordPad | FileInfo lists both for the Fallout text kind. They show the lines of a Fallout file. |
| 7-Zip | Version 23.01. It opened 39 of 41 MSG files as a Compound archive and listed their streams. It shows raw parts and not a message. |
| olefile | Version 0.47. A Python library that opened all 41 MSG files and listed their streams. |
| extract-msg | Version 0.58.0. A Python library under the GPL 3 that reads the message itself. It opened 37 of 41 MSG files. |
| msg_parser | Version 1.2.0. A Python module that opened all 41 MSG files. |
| The file command | Version 5.45. It named 40 of 41 MSG files as Outlook messages. |
Open an MSG file on Linux
file -b example_sent_unicode.msg
CDFV2 Microsoft Outlook Message
7z l example_sent_unicode.msg (abridged)
Path = example_sent_unicode.msg
Type = Compound
Physical Size = 53760
Extension = compound
Cluster Size = 512
Sector Size = 64
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
..... 130 192 __substg1.0_0E03001F
..... 66 128 __substg1.0_00410102
..... 16 64 __substg1.0_001A001F
2010-01-11 16:26:23 D.... __nameid_version1.0
..... 16 64 __nameid_version1.0/__substg1.0_10090102
python3 -c "import extract_msg; m = extract_msg.openMsg('example_sent_unicode.msg'); print(m.subject)"
This is a test message please ignore
The file command names the Outlook message, and 7-Zip lists the raw streams. The extract-msg library prints the subject, which is the first sign that a reader understands the message and not only the container.
Viewers and converters for MSG files
This link opens an outside page. It describes a free viewer from FreeViewer. We describe it from its own page and tested it on nothing.
The page lists 8 preview modes, including Hex and MIME, and says the program works on Windows without Outlook. It says Pro adds PDF export, printing and advanced search, and Pro+ adds export to PST, EML and MBOX. We list no prices, because they change.
What to use for every kind
Outlook messages. If Outlook is installed, open the MSG file there. Without Outlook, use a viewer from the table, or read the streams with olefile as shown above.
Fallout game text. Open the file in any text editor. FileInfo lists Notepad and WordPad, and the game reads the lines itself.
Old program files. For the FoxPro, OS/2 and SmartWare records we found no sample and no modern program. Read the first bytes and the source page first.
Install programs from their makers. Take Outlook from Microsoft and other tools from their own pages. A free site that offers to open any MSG file receives your message, so try the steps on this page first.
How Do You Check an MSG File? Six steps and a script of 22 lines
Check an MSG file in six steps. Read the first 16 bytes, name the type, use a script and compare two readers. Our 22 line script passed all 41 healthy MSG files and flagged or warned on 14 of 21 damaged copies.
First reads need no Python. The xxd command prints bytes, and wc prints the length. The length of a healthy MSG file minus 512 divides by 512, and 53,760 does.
xxd -l 16 example_sent_unicode.msg
00000000: d0cf 11e0 a1b1 1ae1 0000 0000 0000 0000 ................
wc -c < example_sent_unicode.msg
53760
Read the first line from the left. Bytes 0 to 7 are the signature. The length, 53,760 minus 512, leaves 53,248, which is 104 sectors of 512 bytes.
Check MSG files with Python
The script reads the signature, the version and the byte order of an MSG file. It opens the container with olefile and looks for the property stream. It checks that the stream size fits a header of 32 bytes plus entries of 16 bytes.
It then reads the recipient and attachment counts and compares them with the storages. It prints the message class and a tail check, then OK, WARN or FLAG. It never changes an MSG file.
import sys, struct, olefile
def peek(path):
b = open(path, 'rb').read()
if b[:8] != bytes.fromhex('d0cf11e0a1b11ae1'): return 'FLAG', 'start is not D0CF11E0A1B11AE1'
major, bo, ss = struct.unpack('<HHH', b[26:32])
if major not in (3, 4) or bo != 0xFFFE: return 'FLAG', 'CFB version or byte order'
tail = (len(b) - 512) % (1 << ss)
try: o = olefile.OleFileIO(b)
except Exception as e: return 'FLAG', 'directory: ' + str(e)[:40]
if not o.exists('__properties_version1.0'): return 'FLAG', 'no property stream'
p = o.openstream('__properties_version1.0').read()
if len(p) < 32 or (len(p) - 32) % 16: return 'FLAG', 'property stream size'
rc, ac = struct.unpack('<II', p[16:24])
kids = {x[0] for x in o.listdir(streams=False, storages=True) if len(x) == 1}
if sum(k.startswith('__recip_') for k in kids) != rc: return 'FLAG', 'recipient count'
if sum(k.startswith('__attach_') for k in kids) != ac: return 'FLAG', 'attachment count'
cls = next((o.openstream(s).read().decode('utf-16le' if s.endswith('1F') else 'latin-1').rstrip('\0')
for s in ('__substg1.0_001A001F', '__substg1.0_001A001E') if o.exists(s)), '?')
return ('WARN' if tail else 'OK'), '%s, %d recipients, %d attachments, %d bytes%s' % (cls, rc, ac, len(b), ', %d byte tail' % tail if tail else '')
for f in sys.argv[1:]:
r, why = peek(f)
print(r, why, f)
Here is what it printed for four healthy MSG files. They are an empty message, a small one, our example and the largest file.
python3 msg_peek.py blank.msg simple_test_msg.msg example_sent_unicode.msg lots-of-recipients.msg
OK IPM.Note, 0 recipients, 0 attachments, 6656 bytes blank.msg
OK IPM.Note, 1 recipients, 0 attachments, 16896 bytes simple_test_msg.msg
OK IPM.Note, 8 recipients, 1 attachments, 53760 bytes example_sent_unicode.msg
OK IPM.Note, 1321 recipients, 1 attachments, 2105856 bytes lots-of-recipients.msg
Every answer starts with OK, WARN or FLAG. A healthy answer then gives the class, the counts, the length and the file name.
python3 msg_peek.py A1_signature_changed.msg A3_sector_shift_12.msg B2_cut_to_half.msg B5_crlf_text_mode.msg C1_bit_flip.msg C2_recip_count_plus1.msg
FLAG start is not D0CF11E0A1B11AE1 A1_signature_changed.msg
FLAG no property stream A3_sector_shift_12.msg
WARN IPM.Note, 8 recipients, 1 attachments, 26880 bytes, 256 byte tail B2_cut_to_half.msg
FLAG no property stream B5_crlf_text_mode.msg
OK IPM.Note, 8 recipients, 1 attachments, 53760 bytes C1_bit_flip.msg
FLAG recipient count C2_recip_count_plus1.msg
A1 does not start with the signature. A3 opens but has no property stream. B2 is cut to half and leaves a tail of 256 bytes. B5 has no property stream, and C2 has a count that no longer matches. C1 passes, because its flipped bit lies outside the parts the script reads.
What the script found in our MSG files
| Result | Cases |
|---|---|
| Passed (38 healthy MSG files) | The signature, version and byte order are right, the directory opens, the property stream has a fitting size and the counts match the storages. |
| Warned (3 healthy MSG files, B1, B2) | A tail that does not fill a sector. One regular file and two fuzz test files have one, and so do the cuts B1 and B2. |
| Start is not the signature (A1, B6) | A changed byte in the signature or a lost first byte. Both flagged. |
| Header fields (A2, A3, A4, A5) | A2 and A4 print CFB version or byte order. A3 and A5 print no property stream. |
| Counts and names (C2, C3, C5) | C2 and C3 print the count that no longer matches the storages. C5 prints no property stream. |
| Cuts and text mode (B3, B5, C6) | B3 prints a directory error. B5 and C6 print no property stream. |
| Passed (A6, A7, B4, B7, C1, C4, C7) | The header, directory and counts are sound, so the script passes them. B4 is harmless. The other six differ or refuse in at least one reader. |
The script has limits. It does not read the values, so it passes A6, A7, B4, B7, C1, C4 and C7. It repairs nothing. The repair commands fix the 12 kinds of damage we tested.
Check order for any MSG file
- Copy your MSG file, write its SHA256 hash and work on the copy.
-
Read the first 16 bytes. The signature
d0 cf 11 e0 a1 b1 1a e1means a compound file, and readable lines mean the Fallout text kind. See the list of kinds. - Name the type with the file command. CDFV2 Microsoft Outlook Message is the answer you want. A longer name like Composite Document File V2 Document means another kind of compound file or a file it cannot read inside.
- Use our script. The first word is OK, WARN or FLAG, and a flag names the part where the MSG file stops making sense.
- List the streams with 7-Zip or olefile and read the subject with extract-msg. Compare at least two readers, because one reader can return wrong data without an error.
- Ask the sender for the MSG file again or for its hash. Only Outlook shows whether a message displays, and we tested none.
Is an MSG File Safe to Open? Reading is safe, and the attachments need care
Reading the bytes of an MSG file starts nothing, so it is safe. Treat the attachments inside it with care, because an MSG file stores them as Outlook does.
We started no attachment. Our readers only read bytes. Our MSG files are public test data from the Apache POI project, and we scanned none for malware.
Microsoft says Outlook blocks some attachment types because they can contain viruses. A blocked file stays in the message, but you cannot save, open or print it in Outlook. The article does not name .msg and points to a separate page for the full list.
A message inside a message
An attachment can be another MSG file. Two of our MSG files contain an embedded message, stored in a storage named __substg1.0_3701000D. extract-msg raised an AttributeError on both, so use a second reader on a message that contains another message.
A Fallout text file
A Fallout message file is plain text, per FileInfo. Reading it in Notepad starts nothing. Back it up before you edit a file in a game folder, because the game reads those lines itself.
A message from a stranger
Open the MSG file in a viewer that shows the text and the headers first. The FreeViewer page lists Header and Hex modes for that. Check the sender and the attachment names before you open anything.
Not sure? Check it first. Copy the hash, read the first bytes with our check steps and ask the sender where the MSG file came from. Open attachments last.
Why Will Your MSG File Not Open? Eight causes, and what to do about every one
Most MSG files that will not open fail for one of eight reasons. Read the first bytes, name the type and use the script. Our script flagged 14 of 21 damaged copies, and 12 kinds of damage came back byte for byte.
We damaged one MSG file in 21 ways and tested repairs on every healthy MSG file where the damage changes bytes. The table groups what we saw into eight causes.
Every row says what happens to your MSG file and what to try. Fixes work on copies, and none changes the original. We opened no repaired file in Outlook, so a repaired container shows only that the container is sound.
| Cause | Result and fix |
|---|---|
| The wrong kind of file (1) |
The file does not start with d0 cf 11 e0 a1 b1 1a e1, so it is a Fallout text file or another kind, and Outlook refuses it. Fix: Find the kind in the kind chart and open it with a program of that kind.
|
| A signature that is changed or lost (2) |
A1 changes a byte of the signature and B6 loses the first byte. Our script flagged both. Fix: Write d0 cf 11 e0 a1 b1 1a e1 over bytes 0 to 7, or put the lost byte d0 back in front. Both came back byte for byte on all 41 MSG files.
|
| A header field that is wrong (3) |
A2 changes the byte order, A3 the sector size, A4 the version, A5 the first directory sector, A6 the FAT sector count and A7 the cutoff. Fix: Write fe ff at bytes 28 and 29, 9 at bytes 30 and 31 and 3 at bytes 26 and 27. Find the root entry for A5, count the FAT sectors for A6 and write 4,096 at bytes 56 to 59 for A7. All six came back byte for byte.
|
| A copy made in text mode (4) | B5 replaces every newline byte 0a with 0d 0a, so the MSG file grows. Fix: Replace every 0d 0a with 0a. It worked on all 36 files where the damage changes bytes. Use binary mode for transfers from now on. |
| A count that is wrong (5) | C2 raises the recipient count by one and C3 does the same to the attachment count. Fix: Count the recipient and attachment storages and write both counts into bytes 16 to 23 of the property stream. It worked on all 23 files where the header appears once. |
| A stream name that is changed (6) |
C5 renames the property stream, so readers cannot find it. Fix: Restore the underscore at the start of the name __properties_version1.0. It came back on all 41 MSG files.
|
| A file that is cut (7) | B1, B2, B3 and B7 cut the MSG file. Our script warned on B1 and B2, flagged B3 and passed B7. Fix: Ask for a new copy. We tested no repair. B4 adds zero bytes and needs none. |
| Data that is zeroed or flipped (8) | C1 flips a bit, C4 zeroes the message class, C6 zeroes a FAT sector and C7 zeroes half of the MSG file. Our script flagged C6 and passed the other three. Fix: Ask for a new copy or a backup. We tested no repair. |
Repairs we tested
One short script covers all 12 fixes. It takes a damaged file, a kind code and a name for the new file. The commands after it are the ones we used, with short file names.
import sys, struct, olefile
SIG = bytes.fromhex('d0cf11e0a1b11ae1')
def fix(b, how):
b = bytearray(b)
if how == 'A1': b[:8] = SIG
elif how == 'A2': b[28:30] = b'\xfe\xff'
elif how == 'A3': b[30:32] = struct.pack('<H', 9 if b[26] == 3 else 12)
elif how == 'A4': b[26:28] = struct.pack('<H', 3 if b[30] == 9 else 4)
elif how == 'A5':
n = 'Root Entry'.encode('utf-16le'); i = b.find(n)
while i >= 0:
t = bytearray(b); t[48:52] = struct.pack('<I', (i - 512) // 512)
try:
if olefile.OleFileIO(bytes(t)).exists('__properties_version1.0'): b = t; break
except Exception: pass
i = b.find(n, i + 1)
elif how == 'A6': b[44:48] = struct.pack('<I', sum(s < 0xFFFFFFFA for s in struct.unpack('<109I', b[76:512])))
elif how == 'A7': b[56:60] = struct.pack('<I', 4096)
elif how == 'B5': b = bytearray(bytes(b).replace(b'\r\n', b'\n'))
elif how == 'B6': b = bytearray(b'\xd0') + b
elif how in ('C2', 'C3'):
o = olefile.OleFileIO(bytes(b)); p = o.openstream('__properties_version1.0').read()
kids = {x[0] for x in o.listdir(streams=False, storages=True) if len(x) == 1}
r = sum(k.startswith('__recip_') for k in kids); a = sum(k.startswith('__attach_') for k in kids)
i = b.find(p[:32]); n = struct.pack('<II', r, a)
if how == 'C2': b[i+16:i+20] = n[:4]
else: b[i+20:i+24] = n[4:]
elif how == 'C5':
n = '_properties_version1.0'.encode('utf-16le'); i = b.find(n)
while i >= 0:
if struct.unpack('<H', b[i+62:i+64])[0] == 48 and b[i+64] == 2 and b[i-2:i] not in (b'\0\0', b'_\0'): b[i-2:i] = b'_\0'
i = b.find(n, i + 1)
return bytes(b)
if __name__ == '__main__':
open(sys.argv[3], 'wb').write(fix(open(sys.argv[1], 'rb').read(), sys.argv[2]))
# 2 signature changed (A1), first byte lost (B6)
python3 msg_fix.py A1_signature_changed.msg A1 A1_fixed.msg
python3 msg_fix.py B6_first_byte_lost.msg B6 B6_fixed.msg
# 3 header fields (A2 to A7 work the same way)
python3 msg_fix.py A5_dir_sector_0.msg A5 A5_fixed.msg
# 4 text mode copy (B5)
python3 msg_fix.py B5_crlf_text_mode.msg B5 B5_fixed.msg
# 5 counts wrong (C2, C3)
python3 msg_fix.py C2_recip_count_plus1.msg C2 C2_fixed.msg
# 6 stream name changed (C5)
python3 msg_fix.py C5_prop_name_changed.msg C5 C5_fixed.msg
# compare with the original
sha256sum example_sent_unicode.msg A1_fixed.msg B5_fixed.msg C2_fixed.msg | cut -c1-12
04e1aad4a057
04e1aad4a057
04e1aad4a057
04e1aad4a057
The last lines compare hashes. The first 12 characters match for the original and the three repaired files, so the repaired files equal the original. Apply only the fix that matches the flag.
Check MSG files that will not open, step by step
We tested the steps on Python 3.13 and Linux. We opened no files in Outlook, and the steps keep the original untouched at every point.
- Copy your MSG file, write its SHA256 hash and work on the copy.
- Name the type with the file command and the four kind questions. Only Outlook messages start with the signature.
- Use our check script. A flag names the part where your MSG file stops making sense.
- Match the flag to a cause in the table above and try its fix on the copy.
- Compare the SHA256 hash of the result with the source if you can get one, and open the result in two readers.
- If one fix fails, do not stack another on top. Go back to the copy and try the next cause.
- Open the repaired file in Outlook. We tested none, so a repaired container is no proof that a message displays.
What to send a helper
Short messages get faster answers. Include the details below and add the script output. Its first word gives OK, WARN or FLAG.
Subject: MSG file will not open
File: name, size in bytes and SHA256 hash
Kind: the output of the file command
Check: the output of msg_peek.py
Program: name, version and the exact words of the error
Source: who sent the MSG file and when it was copied
What no step can fix
Do not try online repair sites. Sites that offer to fix or convert any MSG file receive your upload. A message can contain private mail and attachments. Try the steps above on a copy first.
Can You Convert an MSG File? Yes, to EML and more, and the subject can drop out
You can convert an MSG file to EML and other formats, but check the result. Our test with extract-msg wrote an EML for 35 of 41 MSG files and lost the Subject in 22 of the 35.
Conversion is a common reason to open an MSG file. FileInfo says Outlook can convert MSG files to HTML and PDF, and converter programs write more formats.
A test with extract-msg
We converted every healthy MSG file to EML with the extract-msg method asEmailMessage. It wrote an EML for 35 of 41 MSG files and failed on 6. Four of the six are files extract-msg could not open, and two more failed in the conversion step.
Only 12 of the 35 EML files have a Subject header. 40 of the 41 MSG files have a subject, and the EML dropped it in 22 of the 35. The script below shows one case.
import extract_msg
m = extract_msg.openMsg('example_sent_unicode.msg')
print(m.subject)
e = m.asEmailMessage()
print(e['Subject'])
open('example_sent_unicode.eml', 'wb').write(e.as_bytes())
# prints
This is a test message please ignore
None
The first line prints the subject and the second prints None. The header is missing from the EML in this version, extract-msg 0.58.0. We did not look for the cause. Check the subject, the date and the recipients of every converted file before you delete the MSG original.
A converter program we did not test
The next card opens an outside page from SysTools. We read its description and tested nothing in the program.
The page says the program works on Windows and Mac without Outlook. It lists 13 export formats. They are PST, MBOX, EML, EMLX, PDF, HTML, vCard, CSV, ICS, TXT, MHT, JSON and ZIP.
It says the free demo converts up to 10 items per folder and that the full version removes the limit. We list no prices, because they change.
What every target is for
Keep the original file. Convert a copy and keep the MSG file you have. Check the subject, the date, the recipients and the attachments of every result before you delete anything.
How Does an MSG File Differ From EML, PST and DAT Files? Close neighbors, and only one stores a single Outlook item
MSG files have close neighbors. EML files are text, PST and OST files are Outlook data files, OLM files come from Outlook for Mac and winmail.dat is a TNEF attachment. Only an MSG file stores one Outlook item in a compound file.
Six kinds of file get mixed up with MSG files because they come from the same mail programs. The table lists them next to MSG. Every row ends with its source.
| Type | What separates it |
|---|---|
| MSG |
A compound file that starts with d0 cf 11 e0 a1 b1 1a e1. It stores one Outlook item, with recipients and attachments in storages. Source: Our tests.
|
| EML | One message saved as text, with headers and parts. Our test converted MSG files to it. Source: Our tests. |
| PST | An Outlook data file that stores many items and folders. Source: Our PST page. |
| OST | The offline copy of a mailbox that Outlook keeps for an account. Source: Our OST page. |
| OLM | An export that Outlook for Mac writes. Source: Our OLM page. |
| DAT | The winmail.dat file that some mail systems attach. The IANA registry lists vnd.ms-tnef for it and no type for MSG files. Source: IANA and our DAT page. |
| MBOX | One text file that stores many messages. Source: Our MBOX page. |
MSG or EML
An EML file is text, so a text editor shows its headers. An MSG file is a container with streams, so a text editor shows unreadable bytes. Our test converted MSG files to EML with extract-msg, and the result dropped the subject in 22 of 35 files.
MSG or PST
A PST file stores many items and folders, and an MSG file stores one item. Converters can combine many MSG files into one PST file, as the convert part lists.
MSG or DAT
A winmail.dat file is a TNEF attachment that some mail systems add. IANA lists the type vnd.ms-tnef for it. It is not an MSG file, and our MSG tests do not cover it.
Which one do you have
What Is the MSG File Format Made Of? The facts we could check, and where they came from
MSG is an ending that more than one maker used. Facts below come from our own checks of 41 MSG files and 21 damaged copies. Sources are FileInfo, file-extensions.org, Microsoft and IANA.
| Part | What we could check |
|---|---|
| Maker | Microsoft for the Outlook kind, per FileInfo. Bethesda Softworks for the Fallout kind. |
| Name | FileInfo lists Outlook Message Item File and Fallout game message file. File-extensions.org lists a saved email message, a FoxPro FoxDoc message, an OS/2 help message and a SmartWare intro display file. |
| First bytes |
Outlook MSG files start with d0 cf 11 e0 a1 b1 1a e1, as our 41 MSG files show. Fallout files are plain text lines.
|
| Container | A compound file. Our files use version 3, sectors of 512 bytes and a mini stream cutoff of 4,096. |
| Properties |
A stream named __properties_version1.0 with a header of 32 bytes and entries of 16 bytes, plus one stream for every value, named by tag and type.
|
| Text | Type 001F is UTF 16 and type 001E is 8 bit text. A file uses one kind, and our 41 MSG files split 23 and 18. |
| Sizes | Our files are 3,584 to 2,105,856 bytes long. We have no size data for other kinds. |
| Specification | Microsoft publishes MS-OXMSG, revision 18.0 from 20 May 2025, and MS-CFB for the container. |
| Media type | The file command prints application/vnd.ms-outlook. The IANA registry page we read on 29 October 2026 does not list it. |
| Our tests | 41 healthy MSG files, 21 damaged copies, 6 readers and 12 repairs. The file command, 7-Zip, olefile, extract-msg, msg_parser and a 22 line script all read our MSG files on Linux. |
About the values we list
Facts about the layout come from our own reading of 41 MSG files and from the Microsoft documents. Facts about the other kinds come from the pages we name, and we did not test them.
Where we found no record, we say so. We found no registered media type for MSG files and no sample of the Fallout kind.
What we left out
We opened no MSG file in Outlook, SeaMonkey, eM Client or a web viewer. We had no sample of a Fallout file or of the older records. We scanned no file for malware.
All 41 MSG files come from the Apache POI tests, and three are fuzz test files. Our damaged copies come from one MSG file and change one thing at a time. Files saved by other versions of Outlook can differ from ours.
Sources checked
For the kinds, see FileInfo on MSG files and the file-extensions.org MSG list. For the layout, see the MS-OXMSG specification and the MS-CFB specification.
For the media type, see the IANA media types registry. For Outlook attachments, see the Microsoft note on blocked attachments.
For the readers, see the Apache POI HSMF component, olefile on GitHub, extract-msg on GitHub and msg_parser on GitHub. Every count on this page came from files and scripts in our research folder.
Frequently Asked Questions About MSG Files
What is an MSG file?
An MSG file stores one Outlook email, contact, appointment, meeting or task with its attachments, per FileInfo. Outlook MSG files start with the bytes d0 cf 11 e0 a1 b1 1a e1. The same ending also names a Fallout text file.
How do I open an MSG file?
Open it in Outlook if you have it. FileInfo also lists SeaMonkey and eM Client, and FreeViewer offers a viewer that needs no Outlook. On Linux we read 41 MSG files with the file command, 7-Zip, olefile, extract-msg and msg_parser.
How do I open an MSG file without Outlook?
Try the FreeViewer MSG Viewer or SeaMonkey. You can also read the streams with olefile or extract-msg. We tested the libraries and 7-Zip, and olefile and msg_parser opened all 41 of our MSG files.
Is an MSG file safe to open?
Reading the bytes starts nothing, so reading is safe. The risk lies in the attachments, because an MSG file stores them. Microsoft says Outlook blocks some attachment types because they can contain viruses. Open attachments only from senders you trust.
What is the difference between MSG and EML?
An EML file is a message saved as text, and an MSG file is an Outlook container with streams. Our test with extract-msg wrote an EML for 35 of 41 MSG files and dropped the Subject in 22 of them, so check every converted file.
Can I convert an MSG file to PDF or PST?
Yes. FileInfo says Outlook can convert MSG files to PDF and HTML, and the SysTools page lists 13 export formats including PST. We tested neither. Our own test converted MSG files to EML only.
Why will my MSG file not open?
Eight causes cover what we saw in damaged MSG files. They are the wrong kind, a changed signature, a wrong header field, a text mode copy, a wrong count, a renamed stream, a cut file and zeroed data. Our script flagged or warned on 14 of 21 damaged copies.
How can I check if an MSG file is damaged?
Read the first 16 bytes, name the type with the file command and compare two readers. Our script also reads the counts and the class. It passed 7 of 21 damaged copies, so only a second reader or the sender finds the rest.
Do all readers agree on a damaged MSG file?
No. Four readers disagreed on 15 of our 21 damaged copies, and on 10 copies none of them matched the original. Only one copy, with 512 zero bytes added, read the same in all five tools.
Can a damaged MSG file be repaired?
Some damage to an MSG file can be repaired. Twelve kinds of header, count and name damage came back byte for byte in our tests. Cut files and zeroed data did not, because the bytes are gone. Keep the original and work on a copy.
What MIME type is an MSG file?
The file command prints application/vnd.ms-outlook. We read the IANA registry on 29 October 2026 and did not find that type, so treat it as a label that tools print and not as a registered standard.
How big is an MSG file?
Our 41 MSG files are 3,584 to 2,105,856 bytes long, and the median is 29,696 bytes. The largest has 1,321 recipients. The size depends on the body, the attachments and the recipients.
Still Stuck With an MSG File? Eight routes out, depending on what went wrong
Read the first bytes and use the check script. The cause table lists what to try in order.
The kind questions name the kind from the first bytes, the folder and the program.
Is it a message in another format? The guide to EML files covers one message as text, and the guide to MBOX files covers files that store many messages.
Is it an Outlook data file? The guide to PST files covers data files, and the guide to OLM files covers exports from Outlook for Mac.
Is it a calendar item? An MSG file can store an appointment, and the guide to ICS files covers calendar files.
Does it come from a mail server? The guide to EDB files covers Exchange databases, and the guide to NSF files covers Lotus Notes databases.
Is it a file type you do not know? Browse the file extension resource library, or send it on the submit a file type page.
Do you need the format facts? Read the format part for the container, the streams and the sources of MSG files.