QAreMed
MenuClose

Standard

HL7 v2 conformance testing requirements

HL7 v2 is a framework: for each message event it gives a template intended to be constrained for a specific use, and most elements in that template are optional. Conformance is measured against a message profile that reduces or eliminates that optionality, so testing starts by pinning which profile each side of the interface implements.

Issued by
Health Level Seven International (HL7). Chapter work sits with HL7 work groups, including Infrastructure and Messaging for Chapter 2 Control, Patient Administration for Chapters 3 and 10, and Orders and Observations for Chapters 4 and 7. The V2 Management Group sponsors version 2.9.1.
Edition
Version 2.9.1, published 2024, is the only release HL7's catalogue marks Active. Version 2.5 is separately published as ISO/HL7 27931:2009, and 45 CFR 170.205 names version 2.5.1. HL7 v2 has no clause numbering: its units are chapters, message types, trigger events, message structures, segments, fields and components.
Applies in
International, United States
Source
Publisher catalogue entry, checked 2 September 2026

What does HL7 v2 require of an interface?

Structure, and very little content. HL7 describes the base standard as a framework that "contains numerous message events, and for each event it provides an initial message template (starting point) that is intended to be constrained for a specific use and context". NIST, which builds the tooling, puts the same point in the terms a tester cares about: "The base message template consists mostly of optional data elements."

There are no clause numbers to cite. The units are chapters, message types, trigger events, message structures, segments, fields and components. A message is "the atomic unit of data transferred between systems", made up of "a group of segments in a defined sequence", and a three-character code inside it identifies its type. A segment is "a logical grouping of data fields" with its own three-character Segment ID, required or optional, single or repeating. The occurrence in the real world that causes a message to be sent is the trigger event, and the relationship runs one way only: "The same trigger event code SHALL NOT be associated with more than one message type; however a message type MAY be associated with more than one trigger event code."

Every message opens with MSH, the segment that "defines the intent, source, destination, and some specifics of the syntax of a message". Its attribute table runs MSH-1 to MSH-28 and marks seven fields Must Implement. Every other field in that table has a minimum cardinality of zero, and a second HL7 rendering of the same table agrees on exactly which seven are required.

The required fields of the HL7 v2 MSH segment, with the name, data type and what each field settles.
FieldNameData typeWhat the field settles
MSH-1Field SeparatorSTDefines the character used as a separator for the rest of the message
MSH-2Encoding CharactersSTFive characters in this order: component separator, repetition separator, escape character, subcomponent separator, truncation character. Length 4 to 5
MSH-7Date/Time of MessageDTMWhen the message was created
MSH-9Message TypeMSGMessage type, trigger event and message structure ID, from Tables 0076, 0003 and 0354
MSH-10Message Control IDSTIdentifies the message uniquely, length 1 to 199. The receiver echoes it back in MSA-2
MSH-11Processing IDPTOne of the three values a receiver can reject the message on under the enhanced accept rules
MSH-12Version IDVID"matched by the receiving system to its own version to be sure the message will be interpreted correctly"

The delimiters are declared inside the message itself. The segment terminator is always a carriage return, ASCII 13, and Figure 2-1 of the Control chapter records that this one "cannot be changed by implementers". The field separator sits in the fourth character position of the MSH segment, with the vertical bar, ASCII 124, as the suggested value. The five encoding characters follow at positions 1 to 5: ^ component separator, ~ repetition separator, \ escape character, & subcomponent separator, # truncation character. The chapter then removes the assumption a parser is usually written under: "At any given site, the subset of the possible delimiters MAY be limited by negotiations between applications." Delimiters that appear inside a component "SHALL be escaped", and escape sequences are defined for six characters.

The reply is specified too. Original mode acknowledgement "was replaced by enhanced mode acknowledgment in version 2.2", and "Implementers SHALL always value MSH-15 and MSH-16". Both fields draw on HL7 Table 0155 and its four codes: AL always, NE never, ER error or reject conditions only, SU successful completion only. The outcome comes back in MSA-1 from Table 0008 and its six codes. AA, AE and AR are the original-mode application responses; CA, CE and CR are the enhanced-mode accept responses. CR is returned "if the one of the values of MSH-9 Message Type, MSH-12 Version ID or MSH-11 Processing ID is not acceptable to the receiving application", which makes CR the code a version mismatch surfaces as.

Since version 2.9 the expected replies are written down per trigger event rather than inferred: "As of V2.9, all chapters SHALL include in their trigger event definitions the acknowledgment choreography." The Patient Administration chapter shows what that produces. When the MSH-15 value of an ADT^A01^ADT_A01 message is AL or ER or SU, an ACK^A01^ACK message SHALL be sent as an immediate ack; when it is NE, an immediate ack SHALL NOT be sent.

Which messages will the interface carry?

Fewer than the tables suggest. HL7 Table 0076 holds 159 message-type codes and Table 0003 holds 384 trigger events, while the message maps HL7 itself publishes cover thirteen messages across five chapters, which is a fair proxy for what a health software team meets.

Common HL7 v2 message types, from ADT to ACK, with the chapter that defines each and how HL7 records it.
Message typeChapterWhat HL7 records it as
ADT3ADT message, carrying new or updated demographic and visit information about patients
OML4Laboratory order message
OMG4General clinical order message, the OBR-based replacement for ORM
VXU4Unsolicited vaccination record update
DFT6Detail financial transactions
ORU7Unsolicited transmission of an observation message
MDM9Medical document management
SIU10Schedule information unsolicited
ACK2General acknowledgment message

Message structures are shared between trigger events, and that is where a test set quietly loses coverage. Table 0354 holds 316 message structure codes, and each one names the events that use it: ADT_A01 is used by A01, A04, A08 and A13; MDM_T02 by T02, T04, T06, T08 and T10; SIU_S12 by fourteen events running from S12 to S26. A suite that exercises ADT_A01 once has exercised one of the four events behind it, and a receiver that routes on the structure ID alone has thrown the trigger event away before the business logic sees it.

ORM is where deprecation turns into a test problem. Chapter 4 states "ORM - general order message. Attention: Retained for backwards compatibility only as of v2.4 and withdrawn as of v2.7. Refer to OMG, OML, OMD, OMS, OMN, OMI, and OMP instead", ORM^O01 has no message structure table in that chapter, and Table 0003 marks the O01 trigger event deprecated. HL7 nonetheless still publishes an ORM_O01 message map, on the stated grounds that it covers components "deprecated yet known to still be in use in messages based on older versions". A tester meets ORM^O01 on the wire and does not find it in the current standard.

HL7's own publications also disagree on what some of these messages are called. Table 0003 gives T02 as "MDM/ACK - Original document notification and content" and Chapter 9 heads the structure "Original Document Notification & Content", while HL7's message map page labels MDM_T02 "Document status change notification and content". The same map page labels ORU_R01 "Unsolicited Report Alarm", where Chapter 7 heads it "Observation Message" and Table 0003 gives R01 as "Unsolicited transmission of an observation message". ORM reads "Pharmacy/treatment order message" in Table 0076 and "general order message" in Chapter 4. Write the code into an acceptance criterion and leave the prose label out of it, because the label depends on which HL7 document was open at the time.

Why does a conforming message get rejected at the receiving site?

Because the receiving site is entitled to require what the standard leaves optional, and HL7 states the mechanism in those words: "Profiles reduce or eliminate the optionality (or openness) of the base standard. An example of a constraint is changing optional usage for a data element in the base standard message definition to required usage in the message profile." A message that omits such an element is conformant against the base standard and non-conformant against the profile at the same time, and both readings are correct.

The two vocabularies behind that sentence carry the same letters and different definitions. HL7 says so plainly: "Optionality and Usage often refer to the same concept. Optionality is a term that has been used historically in the HL7 v2 base standard. Usage is the term that is used in the HL7 v2 conformance specification." Each list has seven entries, and they are not the same seven. The usage definitions quoted here come from the HL7 Version 2 Conformance Methodology, which HL7 publishes free on v2.hl7.org as a ballot revision of September 2019 under a draft banner. HL7's catalogue lists Release 1 of that methodology as normative and active, so check the published release before a usage definition is quoted into a contract.

HL7 v2 optionality codes in the base standard OPT column set against the usage codes of the conformance specification, code by code.
CodeOptionality, base standard OPT columnUsage, conformance specification
RRequiredRequired, and must be present in the message instance
RERequired but may be empty, with the field description stating whenRequired to be supported, and may be present in the message instance
OOptionalUsage not yet defined at this stage of specification
CNot in this listUndeclared conditional, on a predicate that may not be defined initially
C(a/b)Conditional on the trigger event or on other fields, where a and b are each R, RE, O or XDeclared conditional, defining exactly the usage for the true and false outcomes
XNot used with this trigger eventNot supported, and must not be present in the message instance
BLeft in for backward compatibility with previous versionsDesignated for removal from a future version, and current use is discouraged
WWithdrawnNot in this list

A bare C on an older specification is a trap of its own. The C and CE usage indicators "were introduced in the conformance specification in version 2.5 and deprecated in version 2.7.1. In version 2.7.1, C(a/b) was introduced, which subsumed C and CE. C equates to C(R/X) and CE equates to C(RE/X)." HL7 adds its own warning next to it: "the definition of 'C' optionality in the base standard does not match the definition of 'C' usage in various versions of conformance section/chapter."

Constraints only ever tighten. "Elements that are 'Required' cannot be relaxed, e.g., changed to 'Optional'", and for an implementation profile every element marked O or undeclared C "must be constrained to R, RE, C(a/b), or X". That gives a document review one question with a yes or no answer: does any element in this profile still read O or bare C?

What counts as a violation is strict; what happens next is a local decision. "In the conformance assessment, no allowance is made for exceptions. Therefore, any content (or absence of content) not explicitly permitted by the message profile is a conformance violation." HL7 then separates the two worlds a finding lands in: "In certification programs, for example, a conformance violation can and should mean a failure, whereas in live interfaces the same violation may result in a spectrum of responses, from rejecting the message to no action whatsoever."

The receiving end is the harder half, and HL7 concedes it: "Assessing receiver-side conformance is often a more difficult task, because it is determined by the consumption of the data and the actions taken on that data. In order to test receiving systems adequately, sufficient acknowledgement and functional requirements must be specified for each element. Such specifications are often out-of-scope for HL7 v2 interface specifications." Sender and receiver hold their own profiles, and "for a successful interface, the requirements for the sender and receiver must be compatible". Comparing those two documents before writing any test is the step described in our approach to HL7 interface testing.

What happens to Z-segments and local fields?

They are permitted, and they are where two conforming interfaces stop understanding each other. The base standard reserves the letter: "All segment ID codes beginning with the letter Z are reserved for locally defined segments. Z Codes SHALL NOT be defined within the HL7 Standard", and the same reservation covers message types and trigger event codes.

What may be extended is bounded, and the bounds are worth reading before a site agreement is signed. "Users MAY develop local Z messages to cover areas not already covered by existing HL7 messages. These SHOULD be composed of HL7 segments where possible. A local Z message MAY consist entirely of Z segments except that it SHALL begin with a MSH segment." Existing segments are treated differently: "Users SHALL NOT modify an existing segment", and on adding local fields to an HL7 segment the standard says the practice, "while not prohibited, is ill-advised", because it "will likely cause conformance problems with the next release of the HL7 standard".

Against a profile the arithmetic is unforgiving: "unexpected content such as a Z-segment (not documented in the profile, and not explicitly allowed) is a conformance violation with respect to the message profile; however, the receiver may choose to ignore the violation and process the message." A Z-segment that both applications depend on and neither document describes therefore passes in production every day and fails the first validation run. The conformance methodology asks for the discipline that closes it: "The use of Z elements in message profile definitions must be specified using the constraint mechanisms defined in this document", and "Extensions should not be used in cases where a concept already exists in the base standard."

A local field that the interface engine forwards and the downstream application silently drops is visible only end to end, which is why testing an EHR integration is scoped from the sending application to the record a clinician reads rather than to the interface engine's own log.

Which version is the interface actually speaking?

Probably not the current one, and probably not the same one at both ends. HL7's catalogue marks exactly one release Active, version 2.9.1, published 2024. Four more are marked Stable: 2.3.1, 2.5.1, 2.6 and 2.8.2. Nine are marked Retired, which is a catalogue state for the product entry rather than a statement about what is running in the field. Version 2.5 is separately published as ISO/HL7 27931:2009, last confirmed in 2023 at stage 90.93. In the United States, 45 CFR section 170.205 incorporates HL7 2.5.1 by reference in four paragraphs, covering electronic submission to public health agencies, syndromic surveillance, immunization registries and electronic laboratory reporting. HL7 Table 0104, the table MSH-12 draws on, lists 17 version codes from 2.0 in September 1988 onwards.

HL7's own pages disagree about which release is current. The Version 2 Product Suite brief still reads "Version 2.7, representing the latest update to the Version 2 Standard, was published in 2011", while the version 2.9.1 brief on the same site reads "Version 2.9.1, representing the latest update to the Version 2 Standard, was published in 2024". Both were read on 2026-09-02, and the suite page's own related-documents list runs through 2.9.1. Take the release date from the per-version brief and treat the suite page as stale.

What a tester leans on across that spread is the standard's own compatibility rule, stated as two axioms: "Old receivers receiving new messages SHOULD be able to continue receiving messages without error. New receivers SHOULD be able to understand old messages." A warning is printed above them: "If an issue is not covered explicitly under these rules, no assumption SHOULD be made that the change is allowed."

The first axiom turns straight into a test case on the receiving side: "the receiver, regardless of its version level, SHALL ignore any message or message constituent it is not expecting without generating an application failure. This does not preclude a receiver notifying the sender that additional element was ignored, but the receiving application SHOULD NOT fail just from the existence of additional element." New fields are added at the end of a segment and new components at the end of a data type. A parser that walks a segment positionally to the end of the line therefore meets each new version before anything else does.

The rules for changing an element run one way. "Existing optional fields MAY be made conditional or required", while repeatability only widens: "A field MAY be changed from non-repeating to repeating ... A field SHALL NOT be changed from repeating to non-repeating." Nothing is deleted; it is deprecated, with the standard language "Retained for backward compatibility only in version 2.x; refer to section n.m instead", and "Implementers, by site agreement, MAY agree to not support deprecated message constituents." Those site agreements are what breaks on upgrade, because they sit outside the standard and usually outside the interface specification as well. HL7 hedges the whole subject in its own benefits list, where the wording is "Generally backward compatible".

One rule ends the argument about which version's conformance chapter governs a review. The Conformance Methodology "serves to replace (override) the conformance methodology in these earlier versions", so "if a specifier is seeking to constrain a version 2.5.1 message, they must use the conformance methodology prescribed in this document and not the conformance methodology given in version 2.5.1". Its use in a production setting is optional and recommended; for any newly balloted HL7 v2 implementation guide, its inclusion is required.

Whether a new interface should be built on v2 at all is a different question, taken up in HL7 v2 compared with FHIR and in FHIR R4 conformance testing requirements.

Which artefacts does the receiving side ask for?

The conformance profile first, because it is the only artefact a machine can test against. NIST: "Each conformance (message) profile can be exported as XML. These XML conformance profiles ... provide a machine-computable definition of the message interface, enable message validation, facilitate test case and message generation, and even support source code generation." A sending system can assert which profile it claims inside the traffic itself, in MSH-21 Message Profile Identifier, data type EI with cardinality 0 to many, and HL7 notes that "validation tools conduct conformance testing based on the message instance and the conformance claim indicated by the message profile identifier".

Around that profile sit five more documents, each with a job a reviewer can describe.

HL7 v2 conformance artefacts a receiving side asks for, from implementation guide to test data, each described in HL7's or NIST's words.
ArtefactWhat it is, in HL7's or NIST's words
Implementation guide"provides a broader context in which typically a set of message profiles are used to satisfy one or more use cases", and carries a conformance clause defining what must conform and how conformance can be met
Conformance claim"a declaration by an implementer of the requirements in the conformance clause that their implementation satisfies"
Message inventoryOne profile per interaction. "an interaction has a one-to-one relationship with a message profile", and a roundtrip of them "is referred to as a transaction"
Validation reportGenerated when "the validation engine interprets the requirements documented in the XML profile and makes corresponding assertions against the message instance"
Test plan, test cases and test dataProduced by "a tool for creating test plans, test cases, and associated test data, ensuring comprehensive testing coverage", with negative scenarios explicitly in scope

The validation report is the artefact a defect is reproduced from, so its element location notation is worth agreeing in advance. HL7 writes a field as PID-1, a component as PID-3.4 and a subcomponent as PID-3.4.1; a segment group prefix disambiguates a segment that appears twice, as in ORDER_OBSERVATION.OBSERVATION.OBX against ORDER_OBSERVATION.SPECIMEN.OBX; and the message structure can be prepended, as in ORU_R01.MSH-12. NIST's General Validation Tool groups its findings as Errors, Warnings, Alerts and Code Not Found, each row carrying a path, a description and a line number.

NIST offers the tooling "as public domain resources" and names six uses for it, among them the ONC Health IT certification in support of CMS Meaningful Use, IHE Connect-a-thon testing events and AIRA assessment. Its suites are published per domain for immunization, syndromic surveillance, laboratory results and patient care devices, and the ones NIST labels for 2015 Edition and 2024 SVAP certification are what a product going through the ONC certification programme meets. Two kinds of run are available: "Context-free testing tests a message based on the technical requirements without any context. Context-based testing provides additional testing capabilities through the means of directed test cases and example messages." NIST's own fact sheet and the instance that actually answers print different hostnames for the General Validation Tool, so confirm the address before it goes into a test plan.

NIST also draws the boundary that decides how much of an acceptance suite conformance testing can carry: "The intent of HL7 v2 is specifically scoped to defined requirements for exchanging data between applications. The specifications typically do not impose requirements on how the data is processed. ... Data quality, business rules, and functional requirements are necessary to satisfy the desired outcome of the use case scenario." A rule such as a date of administration having to fall after the date of birth is a data quality constraint added on top, never a finding the base standard produces.

The test message set carries its own handling question. An ADT feed transmits demographic and visit information about patients, so a set captured from production puts PHI into the test environment, and the terms on which an outside team may touch it are raised at how we work with protected health information. Building the set from generated instances instead is covered in synthetic test data for healthcare systems.

Where does HL7 v2 interface work go wrong?

  • The interface specification is a word processor document. NIST names the consequence directly: guides "created using word processing programs, resulting in ambiguous and inconsistent specification of requirements".
  • The profile still carries O usage on elements the receiving application in fact requires, so no assertion can be written and no acceptance criterion can be failed.
  • MSH-21 is empty in every message, so nothing in the traffic says which profile the sender claims and a validator has to be pointed at one by hand.
  • The suite covers ADT_A01 once and the four trigger events sharing that structure are recorded as tested.
  • A Z-segment carries a field both applications depend on and appears in neither profile, so a validation run reports a conformance violation on traffic that works.
  • An HL7 segment is extended with local fields at the end, a practice the standard calls ill-advised and warns will likely cause conformance problems with the next release.
  • MSH-15 and MSH-16 are left empty, although the standard says implementers SHALL always value them, and the acknowledgement behaviour is inferred from what the interface engine happens to do today.
  • Deprecated constituents are still populated. MSA-3 and MSA-6 carry cardinality 0 to 0 and were withdrawn and removed as of version 2.7, with the reader referred to the ERR segment.
  • Only the happy path exists. Nothing exercises AE, AR, CE or CR, so the rejection path is first read in production.
  • Receiver-side behaviour is untested, because the specification says what may be sent and never what the receiver does with it once it arrives.

How do we test an HL7 v2 interface against its profile?

The profile is the specification, and where no profile exists the first output is one. The base standard cannot fail a message on its own, so a test plan written against "HL7 v2" produces findings nobody is obliged to fix.

How the scope is set

  1. Collect the interface specification from each side. Record the version each endpoint sends in MSH-12.
  2. Build the message inventory as interactions. Write one profile per interaction and pair the profiles into transactions.
  3. Constrain every O and every undeclared C to R, RE, C(a/b) or X. Write the predicate for each conditional element.
  4. List every element the receiving site requires that the base standard leaves optional. This list is the defect report written before the defects occur.
  5. Register each Z-segment, Z-field and local extension the interface depends on.
  6. Document the acknowledgement choreography per trigger event against MSH-15 and MSH-16.
  7. Validate message instances against the profile. Add a negative case for each rejection code the interface can return.
  8. Report each finding by element location, for example ORU_R01.MSH-12 or PATIENT.PID-3.

The output is the artefact list above: a profile per interaction, an inventory of what crosses the boundary, a validation report per instance, and a message set the receiving site can replay. The wider engagement is described under healthcare interoperability testing.

Base standard quotations on this page were read from Internet Archive captures of HL7's free V2+ web publication, 2021Jan, because v2plus.hl7.org refused connections on 2026-09-02: Chapter 2 Control from the capture of 2024-04-09, the MSH segment from 2024-11-02, the MSA segment from 2023-03-30, and Chapters 3, 4, 6, 7, 9 and 10 from captures of 2022-09-30. Conformance quotations come from the HL7 Version 2 Conformance Methodology published free by HL7 at v2.hl7.org, which is the R1 O1 ballot revision of September 2019 and carries the banner "Draft Website - For Review Purposes Only"; HL7's catalogue lists Release 1 as normative and active, and this page does not assert that the published normative text is identical to the draft. Code tables, catalogue states and release dates were read on 2026-09-02 from terminology.hl7.org and from the HL7 Version 2 Product Suite brief, and the CFR paragraphs from the eCFR.

What do you receive?

Conformance profile per interaction, exported as XML
Gives a validator a machine-computable definition of the interface to test message instances against, which the base standard on its own does not provide
Message inventory of interactions with acknowledgement choreography
Lets a reviewer see one profile per interaction and the immediate and application acknowledgements expected for each trigger event
Usage difference matrix, base standard against site profile
Names every element the receiving site requires that the base standard leaves optional, which is the list a conforming sender fails on
Z-segment and local extension register
Records each locally defined segment, field and message the interface depends on, so a version upgrade can be scoped before it is booked
Validation report per message instance
Names each finding by element location, so a defect can be reproduced from the exact message that produced it
Test message set with positive and negative cases
Gives the receiving site the instances its own regression run replays, including the invalid ones that exercise the rejection codes
Version compatibility record across the endpoints in scope
Records the version each endpoint sends in MSH-12 and the elements that differ between them, so an upgrade on one side has a baseline

What do buyers ask about this?

Who certifies that an HL7 v2 interface conforms?
Nobody certifies conformance to HL7 v2 in general. A conformance claim is a declaration by the implementer against a named message profile, and a validator compares message instances to that profile. Testing programmes are where the claim becomes pass or fail: HL7 writes that in certification programmes a conformance violation can and should mean a failure, while in live interfaces the same violation may result in anything from rejecting the message to no action whatsoever.
Which HL7 v2 version should our test target?
The version each endpoint sends in MSH-12, which is often not the current release. HL7's catalogue marks only version 2.9.1 Active, published 2024, and still marks 2.3.1, 2.5.1, 2.6 and 2.8.2 Stable. Version 2.5 is published as ISO/HL7 27931:2009, and 45 CFR 170.205 incorporates version 2.5.1 by reference for public health reporting in the United States.
Are Z-segments allowed, and do they break conformance?
HL7 reserves every segment ID beginning with Z for locally defined segments and permits local Z messages, so a Z-segment is allowed. Against a message profile the arithmetic is still strict: unexpected content such as a Z-segment that the profile does not document and does not explicitly allow is a conformance violation, although the receiver may choose to ignore it and process the message. Documenting each Z element inside the profile is what removes the finding.
Is "HL7 compliant" a usable acceptance criterion?
No. The HL7 conformance methodology separates four things: compliance of a derived specification with the standard, conformance of an implementation with a specification, compatibility between two specifications, and interoperability, the ability of implementations to exchange data and use it as intended. An acceptance criterion has to name the message profile, the role of sender or receiver, and the version, since none of those follows from the phrase.

What does it get confused with?

What does validating your product actually involve?

Answer four questions about your markets, your product type and its integrations. You get the standards that reach you, the artefacts each one asks you to produce, and which of them a test supplier delivers.