The MSH segment is the header of every HL7v2 message and the single most important segment in the message. It declares the encoding characters, names the sender and receiver, identifies the event, and provides the control ID that tracks the message through the integration. Parsing MSH wrong means parsing the rest of the message wrong.
Naming the fields is the discipline. For related walkthroughs, the FHIR knowledge collection collects the surrounding material.
The Fields That Matter
MSH carries a small set of fields that every parser needs to read:
- MSH-1: field separator (usually
|). - MSH-2: encoding characters (
^~\&by default). - MSH-3 and MSH-4: sending application and facility.
- MSH-5 and MSH-6: receiving application and facility.
- MSH-7: message datetime.
- MSH-9: message type and event (like
ADT^A01^ADT_A01). - MSH-10: control ID.
- MSH-12: version ID.
A pass through the site's HL7 v2 segment → FHIR mapping tool surfaces the mapping between these fields and their FHIR resources.
The Encoding Character Trap
MSH-1 and MSH-2 declare the delimiters used in the rest of the message. Most implementations use the defaults, but not all. Parsers that assume defaults produce silently wrong results on messages that use different characters.
Every parser should read MSH-1 and MSH-2 first and use them as the delimiters for the rest of the parse. For the wider parsing framing, reading an HL7v2 message when you only know FHIR covers the message anatomy.
Sender and Receiver Are Routing Information
MSH-3 through MSH-6 name the sending application, sending facility, receiving application, and receiving facility. Integration engines route based on these fields; message brokers filter on them; audit trails record them.
Getting these fields right is not a v2 optimization; it is what makes multi-tenant integration work. Wrong sender/receiver values produce messages routed to the wrong downstream system.
The Message Type Determines Structure
MSH-9 combines the message type (like ADT), the event (A01), and the message structure (ADT_A01). The structure tells the parser which segments to expect.
Parsers that only read the type miss the event; parsers that only read the event miss the structure. Read all three; each has an operational consequence downstream.
Control ID for Traceability
MSH-10 carries a unique control ID that identifies the message. Every acknowledgment references the control ID. Every audit trail records it.
Systems that generate weak control IDs (timestamps only, not-quite-unique counters) end up with tracing gaps when two messages share an ID. Generate a real UUID or a monotonic ID with high enough resolution to remain unique. For the ACK-side story, acknowledgment codes: AA vs AE vs AR in production covers what happens with the control ID after receipt.
Version ID Matters More Than It Looks
MSH-12 declares the v2 version (2.5, 2.5.1, 2.6, etc.). Different versions add and change fields. Parsers that assume a version usually work until they meet a message from a different version.
Every parser should respect the version and pick the right schema. Multi-version integration is common and does not go away.
FHIR Mapping of the MSH Fields
MSH fields do not have a single FHIR home. Sender and receiver map to Device and Organization resources or to metadata on the containing message. Control ID often maps to Bundle.identifier when the message is delivered as a FHIR Bundle. For the pattern-level framing, MLLP framing: the wire format that never dies covers the transport that carries MSH.
MSH is not glamorous. It is the segment the rest of the integration relies on.

Sources
- HL7 canonical product overview describing MSH header - HL7 canonical product overview describing MSH header structure
