Why valid health data gets rejected downstream
A message can pass every rule in the HL7 v2 or FHIR R4 base standard and still be rejected by the partner that receives it. The receiver checks it against an implementation guide that adds rules of its own, and the rejection comes back days later, with little context, to a team that thought the message was fine. This guide covers the four causes behind most of these rejections and a triage runbook that clears them.
Valid for the standard is not valid for the receiver
The base standards are deliberately permissive. In FHIR R4 most elements are optional, and value sets are often bound loosely so that many organizations can use the same resource. An implementation guide narrows that: it publishes profiles that make elements required, fix their cardinality, bind them to specific value sets and add invariants that a resource must satisfy. HL7 v2 works the same way through conformance profiles and each partner’s interface specification.
So “valid” always needs a second question: valid against what? A sender that validates only against the base standard will pass messages the receiver is bound to reject.
Four causes behind most rejections
1. Rules the implementation guide adds
A profile can make an element required that the base resource leaves optional, require a particular identifier system, or bind a coded element to a value set with required strength, which means a code from anywhere else is an error rather than a warning. The message is well formed; it simply breaks a rule the sender never checked.
2. Empty, null and default are not the same thing
In HL7 v2 an empty field and a field holding two double quotes
("") mean different things: the first says nothing was
sent, the second tells the receiver to delete the value it already
holds. In FHIR an absent element is not the same as an element
carrying a dataAbsentReason extension that explains why
the value is missing. Mapping code that fills gaps with a default,
such as an “unknown” code where nothing was recorded,
turns a missing value into a false one, and a receiver that checks
for it will reject the message or, worse, accept the wrong value.
3. Repeating fields parsed as a single value
HL7 v2 separates repetitions with ~, components with
^ and subcomponents with &, and the
characters actually in use are declared in MSH-2. A patient
identifier list or a phone number field can repeat; a parser that
keeps only the first repetition, or splits on the wrong character,
drops or garbles data without raising an error. The same happens
when a FHIR array such as identifier or
telecom is flattened into one column and written back
out.
4. Codes from the wrong system
A local lab or diagnosis code that was never mapped, or a standard code sent with the wrong code-system identifier, fails a binding even when the meaning is right. These failures cluster: one unmapped local code can reject every message that carries it.
Check before release, not after rejection
The cheapest place to catch a downstream rejection is a validation gate in front of each outbound feed: check each message against the base standard and the receiving partner’s profile or specification before it leaves. For FHIR that means running a validator loaded with the partner’s implementation guide package; for HL7 v2, checking against the partner’s conformance profile.
A message that fails goes to a triage queue rather than to the partner, and each entry records enough to act on: the rule that failed, the element path, the partner, the source message and when it arrived. After a fix, the message is replayed through the same gate, so nothing is resent by hand.
A triage runbook you can adopt
Three numbers tell you whether the runbook is working: rejections by rule and partner, the time from a failure to its successful replay, and how often a rule you already fixed fails again.
Checklist
- Each outbound feed is validated against the receiving partner’s profile or specification, not only the base standard.
- The implementation guide version each partner uses is recorded, and checked when the partner announces a change.
- Mappings keep empty, explicit-null and defaulted values distinct.
- Parsers read every repetition and use the delimiters declared in MSH-2.
- Every local code in an outbound feed has a mapping to the bound value set.
- Failures go to a triage queue with the rule, element path, partner and source message attached.
- Fixed messages are replayed through the gate, and each fixed rule has a regression case.
How Netspective works on this
Netspective engineers have built HL7 v2 and FHIR validation engines and clinical ingestion pipelines for regional health information networks. In a healthcare data lake engagement the validation gate and triage queue run inside your own AWS account or Azure subscription, under your keys, and the rules live in your repository.
Sources
- HL7 International, FHIR R4: Profiling FHIR (profiles, cardinality and implementation guides).
- HL7 International, FHIR R4: Using Codes in Resources (value set binding strengths).
- HL7 International, FHIR R4: Validating Resources.
- HL7 International, FHIR R4: the data-absent-reason extension.
- HL7 International, HL7 Version 2.5.1, Chapter 2 (encoding rules, delimiters and the meaning of
"").
Get the checklist and future updates
One field. We send this guide’s checklist and a note when the guide changes, and nothing else. Your email is read only by Netspective administrators and deleted after 24 months.