Comparison
HL7 v2 vs FHIR
They coexist. A US-certified EHR runs both: 45 CFR 170.205 adopts HL7 2.5.1 for public health submission, and 170.215(a)(1) adopts FHIR Release 4.0.1 for the API. The choice belongs to the receiving endpoint, one data flow at a time. What goes untested is the crossing between them, where neither conformance regime looks.
- Compared
- HL7 v2 messaging and FHIR R4 RESTful API
- Written for
- For a CTO
- What follows from it
- A conformance pass on the v2 feed and a conformance pass on the FHIR endpoint can both be genuine while the same patient reads differently on the two sides. The mapping between them is a third artefact, it is Trial Use, and no validator on either side is pointed at it.
Which of the two are you actually being offered?
Whichever the endpoint on the other side serves for that direction of travel, and a single hospital usually serves both. US regulation writes the split down. 45 CFR 170.215(a)(1) adopts "HL7 Fast Healthcare Interoperability Resources (FHIR) Release 4.0.1" as the API base standard, with US Core STU 6.1.0 named at 170.215(b)(1)(ii) and consumed by the certification criterion at section 170.315(g)(10). Four paragraphs of 45 CFR 170.205 in the same part keep HL7 2.5.1 incorporated by reference for the public health reporting flows, at (d)(2), (d)(4), (e)(4) and (g). Both adoptions are live in the same CFR part at the same time, and each carries its own version pin.
So a product integrating with a certified EHR does not choose a protocol. It inherits one per flow, and it inherits the version the other side runs, which on the v2 side is rarely the current release. HL7's own V2-to-FHIR work says why plainly: the guide "aims to address all message structures, segments, and data types that are represented in the latest HL7 v2 version and any components that were deprecated yet known to still be in use in messages based on older versions". What the certification criteria measure and which versions they name is where the regulatory half of that sentence is set out.
The practical reading for a CTO planning a year of integration work: budget for two conformance regimes, and then budget for a third piece of work that belongs to neither.
What happens to a fact when it crosses from a message to a resource?
It passes through a mapping that no validator on either side is holding. HL7 publishes the mapping as a separate implementation guide, version 1.0.0 STU 1, standards status Trial-use, generated on 7 October 2025. That guide covers thirteen message maps across five v2 chapters, running from ADT_A01 through OML_O21, ORU_R01, MDM_T02 and SIU_S12, and it states that it "represents a cumulative mapping of the standard, not any HL7 v2 based implementation guide", so it is pinned to no particular v2 version.
Two consequences land on a test plan. The mapping artefact is less settled than either of the things it joins, and the evidence from the two sides cannot be lined up by location. HL7 v2 addresses a value positionally: a field is written PID-3, a component PID-3.4, a subcomponent PID-3.4.1, and a group prefix disambiguates a repeated segment, as in ORDER_OBSERVATION.OBSERVATION.OBX. FHIR addresses a value by element path and, where a profile has split a repeating element, by discriminator. R4 states that slice names "are never exchanged", so a finding on the FHIR side carries no field number to hand back to the interface team.
The cheapest place to catch this is a write over one protocol and a read over the other, which is treated as a route in how an EHR integration is tested end to end.
What does each side do with content it was not expecting?
The two defaults are opposites, and the same arriving surprise produces a different correct behaviour on each side.
HL7 v2 tells the receiver to absorb it. The compatibility rules state that "the receiver, regardless of its version level, SHALL ignore any message or message constituent it is not expecting without generating an application failure", and add that 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, so the surprise arrives at the far end of the line a parser is already walking.
FHIR splits the same event in two. On ordinary extensions R4 agrees with v2: "applications should not reject resources merely because they contain extensions, though they may need to reject resources because of the specific contents of the extensions". On modifier extensions it reverses: an application "SHALL refuse to process the resource or affected element, or SHALL provide an appropriate warning to its users", and applications "SHALL always ensure unrecognized modifier extensions are not present when processing the data from any element that might have carry modifier extensions".
| Arriving content | HL7 v2 expected behaviour | FHIR R4 expected behaviour |
|---|---|---|
| An element the receiver does not know | Ignore it, without an application failure | Do not reject the resource for its presence |
| Content the sender marks as changing meaning | No equivalent marking exists in the message | Refuse to process, or warn the user |
| Undocumented local content | Permitted by the Z reservation, and a conformance violation against a profile that does not document it | The extension url SHALL be the canonical URL of a StructureDefinition that defines it |
The test cases therefore have opposite pass conditions. On the v2 feed you plant an unknown constituent and assert that processing continued and the known fields still landed. On the FHIR endpoint you plant an unrecognised modifier extension and assert that the system stopped. A team that carries one habit across the boundary writes a suite that passes on both and has checked neither.
What does a passing conformance test on one side prove about the other?
Nothing, and the reason is structural rather than a gap in anyone's coverage. The two claims are cut differently, so they cannot be added together.
An HL7 v2 claim is per interaction. HL7 defines an interaction as the exchange between two actors and states that it "has a one-to-one relationship with a message profile", and a sender can assert which profile it claims inside the traffic itself, in MSH-21. A FHIR claim is per endpoint: "systems can only claim FHIR Conformance for functionality described in the applicable CapabilityStatement", and the claim is made against one of three exchange frameworks, RESTful FHIR, FHIR messaging or FHIR documents.
That difference decides what a change costs you. Adding a v2 interaction adds a profile, a claim and a set of instances, and leaves the existing interactions untouched. Changing what a FHIR server offers edits the single document every client reads before it does anything else, because producing that document is the only interaction R4 requires a server to support.
Each specification also limits its own verdict, in its own words. R4 states that "static testing of resource content is not enough to prove conformance to the specification". HL7's v2 conformance methodology states that in certification programmes "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". A finding from one regime cannot be graded on the other's scale. The two run books are set out separately in how an HL7 v2 interface is tested against its profile and in what each FHIR conformance tool actually proves.
What changes when the far end is slow or down?
The v2 feed tells you, and it leaves a receipt. HL7 v2 is written from the premise that a real-world event creates the need for data to flow, and the message it produces is an unsolicited update. The reply is specified with it. MSH-15 and MSH-16 carry a value from a four-code table, AL always, NE never, ER error or reject conditions only, SU successful completion only. The outcome comes back in MSA-1 from a six-code table, and MSA-2 echoes the Message Control ID the sender put in MSH-10, which is what makes a retransmission distinguishable from a second event. Since version 2.9 the expected replies are written down per trigger event, because "all chapters SHALL include in their trigger event definitions the acknowledgment choreography".
The FHIR API answers when it is asked, and its failure surface is designed not to survive. OperationOutcome is what a failed RESTful interaction returns, its severity is one of fatal, error, warning or information, and R4 states that the resource is "not designed to be persisted or referenced from other parts of the workflow". Nothing in the exchange records that a consumer read the value.
What to put in the plan for each direction
- On the v2 feed, test the silence. Stop the receiver, send, and record what the sender does when no acknowledgement arrives.
- On the v2 feed, resend the same MSH-10 and check the record was not created twice.
- On the FHIR endpoint, test the client's behaviour when the server is slow, because the client owns the retry.
- On the FHIR endpoint, capture the OperationOutcome at the point of failure, since nothing else keeps it.
- Compare the two logs for one patient event. Keep that comparison as a standing test case.
FHIR does define a message-shaped exchange as one of its three frameworks. Its central resource, MessageHeader, is the only resource in R4 at maturity level 4, and no R4 resource reaches level 5, so the route exists and sits outside the eleven resources HL7 has marked Normative.
Which end carries the burden of meaning?
HL7 v2 puts it on the sender, and FHIR puts it on the requestor.
On the v2 side the receiving site is entitled to require what the base standard leaves optional: "profiles reduce or eliminate the optionality (or openness) of the base standard". A sender therefore has to be told the local rules and be constrained to them, one site at a time. The receiving half is where the standard concedes the difficulty: "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", and such specifications "are often out-of-scope for HL7 v2 interface specifications". What HL7 v2 requires of an interface, and which usage codes decide a rejection sets out the mechanism.
On the FHIR side the server publishes what it does and the client has to cope with the answer. R4 flags no element as Must Support in the base specification, so the meaning of support is whatever the profile author wrote down. Under US Core a requestor SHALL read a missing data element as data not present in the responder's system, which makes an empty answer a result the client has to grade instead of an error it can raise. Which parts of R4 are stable, and what in a profile is testable covers the profile side of that.
Written into a contract, the two look nothing alike. A v2 acceptance criterion names the receiving site's message profile, the role of sender or receiver, and the version each endpoint sends in MSH-12. A FHIR acceptance criterion names the served CapabilityStatement, the canonical URL of each declared profile, the implementation guide version and the fhirVersion string. A criterion that says "conforms to HL7" covers neither.
Both criteria need the same patient present on both sides before anything can be compared, which makes the test corpus a data question before it is a testing one. The terms an outside team works under are set out at how we work with protected health information.
Building that comparison across an estate that already carries live traffic on both protocols is the engagement described under interoperability testing for healthcare interfaces.
Sources for this page: the HL7 v2 statements are read in Internet Archive captures of HL7's free V2+ web publication and in the HL7 Version 2 Conformance Methodology published at v2.hl7.org as a September 2019 ballot revision, all read on 2 September 2026. The FHIR statements are read in FHIR R4 at version 4.0.1 on the same day. The CFR paragraphs and the SVAP table for the ONC Health IT Certification Program are taken from the eCFR text of 45 CFR part 170 in force on 31 August 2026 and from healthit.gov.
What do buyers ask about this?
- Should a new integration be built on FHIR and the v2 feed retired?
- Ask the receiving endpoint before you decide, because both are named in current US regulation. 45 CFR 170.215(a)(1) adopts FHIR Release 4.0.1 and 170.215(b)(1)(ii) names US Core STU 6.1.0, while paragraphs (d)(2), (d)(4), (e)(4) and (g) of 45 CFR 170.205 hold HL7 2.5.1 in place for immunization registry and laboratory reporting traffic. HL7 itself still publishes v2 message maps on the stated grounds that they cover components "deprecated yet known to still be in use in messages based on older versions".
- Can one test suite cover both protocols?
- Not as one artefact, because the two claims have different shapes. An HL7 v2 conformance claim is made per interaction, and HL7 states that "an interaction has a one-to-one relationship with a message profile". A FHIR claim is made per endpoint: "systems can only claim FHIR Conformance for functionality described in the applicable CapabilityStatement". Adding a v2 interaction adds a profile and a claim. Adding a FHIR resource edits one document that every existing client already reads.
- Which of the two is harder to get evidence out of?
- The v2 feed produces evidence the FHIR API does not. A v2 receiver returns an acknowledgement carrying MSA-1 from a six-code table, and the receiver echoes the sender's MSH-10 back in MSA-2, so the sender holds a durable receipt per message. On the FHIR side the failure surface is an OperationOutcome, which R4 states is "not designed to be persisted or referenced from other parts of the workflow". Any record of a FHIR exchange is one the client built on purpose.
- Does the ONC programme accept a newer US Core than the one in the regulation?
- Yes, voluntarily and through the Standards Version Advancement Process rather than through the CFR text. For 45 CFR 170.315(g)(10) the Approved SVAP Versions table gives the regulatory version as US Core STU 6.1.0 and the approved version as US Core STU 9.0.0, June 2026. The adoption of US Core STU 3.1.1 at 170.215(b)(1)(i) expired on 1 January 2026, so of the two versions written into that paragraph only STU 6.1.0 still has a live adoption.
Which standards does this touch?
Which of our services test it?
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.