FHIR to OMOP FHIR IG, published by HL7 International / Biomedical Research and Regulation. This guide is not an authorized publication; it is the continuous build for version 1.0.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/fhir-omop-ig/ and changes regularly. See the Directory of published versions
| Page standards status: Informative |
Implementers of FHIR-to-OMOP ETL pipelines must account for one of the most consequential—and most frequently overlooked—aspects of the FHIR specification: modifier extensions. Modifier extensions are a formal FHIR mechanism for communicating that a resource's apparent clinical meaning is fundamentally altered by contextual information that the standard resource structure cannot express. This includes negation, repurposing, participant exclusion, reliability qualification, and access constraints.
The risk to observational data quality is severe. A resource that superficially describes a medication order, a diagnosis, or a clinical observation may carry a modifier extension that entirely reverses its meaning — asserting, for example, that a medication must NOT be given, that a condition belongs to a family member rather than the patient, or that a measurement value is unreliable. An ETL pipeline that processes FHIR resources without inspecting modifier extensions will silently introduce false clinical facts into the OMOP CDM, corrupting cohort definitions, prevalence estimates, drug utilization analyses, and any downstream research built on those records.
This guidance covers what modifier extensions are, what the FHIR specification normatively requires of any system that processes resources containing them, a taxonomy of common modifier extension patterns with their correct OMOP dispositions, annotated clinical examples, and concrete ETL implementation guidance.
FHIR's design prioritizes a compact, universally applicable core model. Concepts required by specific jurisdictions, domains, or workflows that fall outside that core are represented using extensions: named, URL-identified elements that carry additional information. Every element in every FHIR resource may carry one or more extension children.
Regular extensions add supplementary information that does not alter the fundamental meaning of the element or resource they annotate. A system that does not understand a regular extension may safely ignore it and continue processing the resource. For example, a Patient resource carrying an extension for citizenship can be correctly processed by any system that understands what a Patient is, even if that system has no concept of the citizenship extension.
Regular extensions are placed in the standard extension element:
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/patient-citizenship",
"valueCodeableConcept": {
"coding": [{ "system": "urn:iso:std:iso:3166", "code": "US" }]
}
}
]
Modifier extensions are categorically different. A modifier extension contains information that qualifies, negates, or otherwise fundamentally changes the meaning of the element or resource to which it is attached. The FHIR specification identifies the following as canonical use cases:
Modifier extensions are placed in the modifierExtension element, which is syntactically distinct from extension in both FHIR XML and JSON:
"modifierExtension": [
{
"url": "http://example.org/fhir/StructureDefinition/anti-prescription",
"valueBoolean": true
}
]
NOTE: The structural distinction between
extensionandmodifierExtensionis the primary machine-readable signal that a system MUST NOT ignore the data in this element. ETL pipelines that generically process or discard all extension data without distinguishing the element name will silently bypass this critical signal.
The FHIR specification imposes normative obligations — using RFC 2119 language of SHALL, SHOULD, and MUST — on any system that processes FHIR resources. These obligations apply to ETL pipelines consuming FHIR data to populate OMOP. The authoritative source for these requirements is the FHIR Extensibility page.
FHIR SPEC REQUIREMENT: "Implementations SHALL ensure that they do not process data containing unrecognized modifier extensions." — FHIR Specification, Extensibility (R4/R5)
When a modifier extension is encountered, a processing system SHALL choose one of the following strategies:
Additional normative guidance from the specification:
MISINTERPRETATION RISK: An OMOP ETL pipeline that reads FHIR resources without inspecting the
modifierExtensionelement at both the resource root and all backbone element levels is non-compliant with the FHIR specification and is at significant risk of ingesting clinically inverted or otherwise meaningless data into the OMOP CDM.
Modifier extensions encountered in practice cluster into several semantic categories. The correct OMOP handling strategy differs by category, and ETL registries should be organized accordingly.
| Category | What It Does | Common Examples | Correct OMOP Disposition |
|---|---|---|---|
| Negation / Absence | Asserts that something explicitly did NOT happen or does NOT apply | anti-prescription (do not give this medication); "hasNotGot" Condition; NLP-derived negation flag | Do NOT map to condition_occurrence / drug_exposure / measurement. Consider mapping to an observation concept if the absence is clinically relevant. Document in ETL metadata. |
| Do-Not-Use Contact | Marks a sub-element as excluded from normal use | do-not-contact flag on Patient.contact |
Process the Patient record normally. Exclude the flagged contact from any contact data mapping. Do not surface this contact to downstream systems without conveying the constraint. |
| Resource Repurposing | Uses a resource for a clinical purpose other than its primary design | Condition resource used to record family history rather than a patient's own diagnosis | Do NOT create a condition_occurrence for the patient. If family history is analytically relevant, map to the observation domain using an appropriate family history type concept. |
| Participant Exclusion | Asserts that a referenced performer or actor was explicitly NOT involved | Performer marked as not involved in a Procedure | Exclude the flagged performer from provider attribution. Map the procedure record using only the non-excluded performers. |
| Reliability / Certainty Qualification | Qualifies a value as unreliable or uncertain such that it should not be used as a confirmed clinical fact | unreliable-measurement on an Observation.component; low-certainty flag |
Exclude the flagged element from standard clinical domain mapping. Map to the observation domain with a qualifier flag, or quarantine for review. |
| Conditional Status | Changes the effective status of the resource in a way not captured by the native status field | Suspended medication or conditional order conveyed via modifier extension rather than a status code | Apply the same exclusion logic used for non-finalized FHIR status values: do not map to OMOP clinical domain tables. |
| Privacy / Security Constraint | Signals that the resource carries access restrictions that limit its use | Restricted record, sensitive demographic flag, consent-limited data | Quarantine from general OMOP ingestion pending data governance review. Log the URL and value for compliance tracking. |
The following examples illustrate real-world scenarios where failure to process modifier extensions results in clinically incorrect data in an OMOP CDM instance.
{
"resourceType": "MedicationRequest",
"modifierExtension": [
{
"url": "http://example.org/fhir/StructureDefinition/anti-prescription",
"valueBoolean": true
}
],
"status": "active",
"intent": "order",
"medicationCodeableConcept": {
"coding": [{ "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
"code": "1049502", "display": "Oxycodone 10 MG Oral Tablet" }]
},
"subject": { "reference": "Patient/example" }
}
This is not a prescription for oxycodone. The modifierExtension with valueBoolean: true for anti-prescription means this is an explicit instruction that the patient must NOT be given oxycodone. This pattern arises in clinical systems that record contraindicated medications within the standard prescribing workflow.
MISINTERPRETATION RISK: An ETL that maps all active MedicationRequests with
intent=ordertodrug_exposureordrug_erarecords will ingest this as a legitimate opioid prescription. This corrupts cohort definitions, drug utilization analyses, pharmacovigilance studies, and any clinical decision support built on OMOP data.
modifierExtension at the resource root.drug_exposure record. Consider mapping to observation to document the contraindication.{
"resourceType": "Condition",
"modifierExtension": [
{
"url": "http://example.org/fhir/StructureDefinition/condition-family-history",
"valueBoolean": true
}
],
"clinicalStatus": { "coding": [{ "code": "active" }] },
"code": {
"coding": [{ "system": "http://snomed.info/sct",
"code": "254837009", "display": "Malignant neoplasm of breast" }]
},
"subject": { "reference": "Patient/example" }
}
This Condition resource is not asserting that the patient has breast cancer. The modifier extension condition-family-history=true indicates the record documents that a family member had breast cancer. This pattern was used in some systems before the FamilyMemberHistory resource was routinely available.
MISINTERPRETATION RISK: An ETL mapping SNOMED Condition codes to
condition_occurrencewill create a record asserting the patient has malignant neoplasm of breast. This false positive causes the patient to appear in cancer cohorts, inflates cancer prevalence statistics, corrupts comorbidity flags, and affects risk-adjustment models.
condition_occurrence for the patient.{
"resourceType": "Patient",
"name": [{ "use": "official", "family": "Smith", "given": ["Jane"] }],
"contact": [
{
"modifierExtension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/patient-doNotContact",
"valueBoolean": true
}
],
"relationship": [{ "coding": [{ "code": "N", "display": "Next-of-kin" }] }],
"name": { "text": "John Smith" },
"telecom": [{ "system": "phone", "value": "555-0100" }]
}
]
}
The patient record is valid. The contact John Smith is listed for record-keeping purposes only. The modifierExtension on the Patient.contact backbone element signals this contact must NOT be contacted. This is a modifier extension on a child element, not the resource root.
MISINTERPRETATION RISK: Any ETL or downstream application that extracts this contact and uses it for outreach, consent verification, or enrollment screening may contact this individual inappropriately, violating patient wishes and creating legal or regulatory exposure.
Patient.contact backbone element, not the Patient root. The Patient record may be safely ingested into the OMOP person table.{
"resourceType": "Observation",
"status": "final",
"code": { "coding": [{ "system": "http://loinc.org", "code": "55284-4",
"display": "Blood pressure systolic and diastolic" }] },
"component": [
{
"code": { "coding": [{ "system": "http://loinc.org", "code": "8480-6",
"display": "Systolic blood pressure" }] },
"valueQuantity": { "value": 142, "unit": "mmHg" }
},
{
"modifierExtension": [
{
"url": "http://example.org/fhir/StructureDefinition/unreliable-measurement",
"valueBoolean": true
}
],
"code": { "coding": [{ "system": "http://loinc.org", "code": "8462-4",
"display": "Diastolic blood pressure" }] },
"valueQuantity": { "value": 88, "unit": "mmHg" }
}
]
}
The systolic reading (142 mmHg) is valid. The diastolic component carries a modifier extension flagging it as unreliable — perhaps due to equipment malfunction or a data entry error. The Observation status of final might otherwise lead an ETL to treat both components as confirmed values.
MISINTERPRETATION RISK: Mapping both components to OMOP
measurementrecords without detecting the modifier extension stores an unreliable diastolic reading as a confirmed clinical fact. Blood pressure analyses, cardiovascular risk models, and hypertension phenotyping algorithms are silently corrupted. Paired systolic/diastolic analyses are particularly affected.
measurement record normally.observation domain with a reliability qualifier.value_as_number to NULL for the diastolic value and preserving a note in value_source_value.{
"resourceType": "Procedure",
"status": "completed",
"code": { "coding": [{ "system": "http://snomed.info/sct",
"code": "80146002", "display": "Appendectomy" }] },
"subject": { "reference": "Patient/example" },
"performer": [
{
"actor": { "reference": "Practitioner/attending-surgeon" }
},
{
"modifierExtension": [
{
"url": "http://example.org/fhir/StructureDefinition/performer-not-involved",
"valueBoolean": true
}
],
"actor": { "reference": "Practitioner/resident-physician" }
}
]
}
The appendectomy was completed and performed by the attending surgeon. The resident physician is listed as a performer, but the modifier extension on the second performer backbone element asserts this practitioner was explicitly NOT involved — possibly listed in error, or present but non-participating.
MISINTERPRETATION RISK: An ETL mapping all listed performers to
provider_idinprocedure_occurrenceincorrectly attributes the appendectomy to the resident physician, corrupting provider performance analytics, surgical outcome studies, and quality metrics.
procedure_occurrence.provider_id.This pattern arises when FHIR resources have been generated by Natural Language Processing pipelines applied to clinical notes. NLP tools such as Apache cTAKES produce structured FHIR output for concepts extracted from text and use modifier extensions to encode negation. FHIR resources from NLP pipelines must be treated as a distinct and higher-risk data category.
{
"resourceType": "Condition",
"modifierExtension": [
{
"url": "http://smarthealth.cards/fhir/StructureDefinition/condition-negated",
"valueBoolean": true
},
{
"url": "http://smarthealth.cards/fhir/StructureDefinition/nlp-source",
"valueString": "Clinician note 2024-03-01: 'No evidence of pneumonia'"
}
],
"code": { "coding": [{ "system": "http://snomed.info/sct",
"code": "233604007", "display": "Pneumonia" }] },
"subject": { "reference": "Patient/example" }
}
The NLP system extracted the concept "pneumonia" from a clinical note and also detected it was negated ("no evidence of pneumonia"). The condition-negated modifier extension communicates this negation. The resource asserts the absence of pneumonia, not its presence.
⚠ MISINTERPRETATION RISK: Mapping this resource to
condition_occurrencecreates a record asserting the patient had pneumonia — the exact opposite of the clinical meaning. At scale, NLP-sourced FHIR data can generate entire populations of records carrying negation modifiers, making this a systemic risk rather than an occasional edge case.
condition_occurrence.observation domain as an "absence of [condition]" entry if clinically relevant.Modifier extensions are not the only FHIR mechanism by which a resource's surface meaning may differ from its clinical intent. Several core resource elements serve a similar modifying function and must be processed correctly alongside modifier extension inspection. The table below summarizes the most important native elements; the FHIR-to-OMOP IG's Status and Intent guidance covers these in detail. Modifier extension inspection is an additional, parallel requirement — not a substitute for processing these fields.
| FHIR Element | Resource(s) | Values That Signal Non-Standard Meaning | OMOP Impact if Ignored |
|---|---|---|---|
status |
Most clinical resources | entered-in-error, cancelled, draft, on-hold, stopped |
Erroneous, cancelled, or planned records ingested as confirmed clinical events. |
verificationStatus |
Condition, AllergyIntolerance | refuted, entered-in-error |
A refuted Condition creates a false diagnosis in condition_occurrence. |
intent |
MedicationRequest, ServiceRequest, CarePlan | proposal, plan (vs. order) |
Planned or proposed medications mapped as completed drug exposures, inflating utilization rates. |
clinicalStatus |
Condition | inactive, remission, resolved |
Resolved conditions appear as ongoing in temporal analyses if end dates are not set. |
dataAbsentReason |
Observation | Any code indicating why data is missing (e.g., not-permitted, error, unknown) |
Missing values stored without context, introducing measurement gaps or apparent zero-values. |
Modifier extensions can appear in two locations within any DomainResource:
modifierExtension array on the resource. This affects the meaning of the entire resource.Observation.component, Procedure.performer, Patient.contact — may carry its own modifierExtension array. This affects only the meaning of that sub-element.ETL code must check both locations. Checking only the resource root is not sufficient.
#### Pseudocode — check modifier extensions before processing
def has_modifier_extension(resource_or_element):
return bool(resource_or_element.get("modifierExtension", []))
def get_modifier_ext_urls(resource_or_element):
return [me["url"] for me in resource_or_element.get("modifierExtension", [])]
def process_medication_request(resource):
# STEP 1: Check resource root
if has_modifier_extension(resource):
urls = get_modifier_ext_urls(resource)
disposition = resolve_modifier_extensions(urls, scope="resource")
if disposition == "REJECT":
log_quarantine(resource, reason="unrecognized-root-modifier")
return
elif disposition == "NEGATION":
log_negation(resource)
return # Do not map to drug_exposure
# STEP 2: Proceed with mapping only if root is clean
map_to_drug_exposure(resource)
Every organization implementing a FHIR-to-OMOP pipeline should maintain a modifier extension registry — a catalog of known modifier extension URLs, their semantics, and the ETL disposition associated with each. This registry should be:
| Extension URL Pattern | Category | ETL Disposition | OMOP Action |
|---|---|---|---|
*/anti-prescription |
Negation | EXCLUDE | Do not create drug_exposure; optionally create observation for contraindication |
*/condition-family-history |
Repurposing | RECLASSIFY | Map to observation domain as family history; do not create condition_occurrence for patient |
*/patient-doNotContact |
Contact constraint | PARTIAL_EXCLUDE | Process Patient root normally; exclude flagged contact from contact data mapping |
*/unreliable-measurement |
Reliability qualifier | QUARANTINE_ELEMENT | Map parent resource; exclude flagged component; flag in value_source_value or note |
*/performer-not-involved |
Participant exclusion | EXCLUDE_ELEMENT | Map procedure; exclude flagged performer from provider_id attribution |
*/condition-negated (NLP) |
Negation | EXCLUDE | Do not create condition_occurrence; optionally map to observation as "no finding" |
| [ANY UNRECOGNIZED URL] | Unknown | QUARANTINE_RESOURCE | Do not ingest. Log resource ID and URL. Route to human review queue. |
The FHIR specification is explicit: a system encountering an unrecognized modifier extension MUST NOT process the resource as if the extension were absent. The recommended handling is:
IMPLEMENTATION TIP: Consider maintaining a quarantine table alongside the OMOP instance, capturing:
resource_type,resource_id,source_system,modifier_extension_url,modifier_extension_value,date_quarantined,review_status,reviewer_notes. This supports both audit compliance and systematic resolution of novel modifier extensions.
For modifier extensions that are understood and lead to a modified ETL disposition rather than outright exclusion, the handling decision should be documented in OMOP to preserve analytical transparency:
*_source_value columns (e.g., condition_source_value, drug_source_value) to preserve original FHIR identifiers and support traceability.observation domain rather than a standard clinical domain table, use appropriate OMOP type concepts to signal the non-standard provenance.NOTE or FACT_RELATIONSHIP tables to link modifier-extension-affected records to documentation of the handling decision.| Step | Action | If Yes | If No |
|---|---|---|---|
| 1 | Does the resource root have a modifierExtension element? |
Proceed to Step 2 | Proceed to Step 5 (check backbone elements) |
| 2 | Is every root modifier extension URL present in the registry? | Proceed to Step 3 | QUARANTINE the entire resource. Log URL. Route to review. |
| 3 | Does any recognized root modifier extension signal negation, repurposing, or exclusion? | Apply the registered disposition. Do not ingest as a standard clinical event. | Proceed to Step 4 |
| 4 | Does any recognized root modifier extension signal a reliability or certainty qualifier? | Map resource with qualifier applied. Flag affected data elements. | Proceed to Step 5 |
| 5 | Do any backbone elements carry a modifierExtension? |
Proceed to Step 6 for each affected element | Proceed with normal ETL mapping |
| 6 | Is every backbone-level modifier extension URL in the registry? | Apply disposition to that element only. Process other elements normally. | EXCLUDE the affected element. Log URL. Process other elements if safe. Route excluded element to review. |
| # | Checklist Item | Status |
|---|---|---|
| 1 | ETL code checks modifierExtension at the resource root for every resource type processed |
[ ] |
| 2 | ETL code checks modifierExtension at backbone element level for all backbone elements within each resource type |
[ ] |
| 3 | A modifier extension registry exists with URLs, semantics, and dispositions | [ ] |
| 4 | Registry covers all modifier extensions from source FHIR systems and IGs in use | [ ] |
| 5 | ETL handles unrecognized modifier extensions by quarantine, not silent pass-through | [ ] |
| 6 | A quarantine audit table exists to log unrecognized extensions with resource ID, URL, and timestamp | [ ] |
| 7 | ETL dispositions are documented in the ETL specification document | [ ] |
| 8 | Modifier extension handling logic is covered by unit tests including negation, repurposing, partial exclusion, and unknown-URL scenarios | [ ] |
| 9 | OMOP data quality queries exist to retrospectively detect potential modifier extension bypass | [ ] |
| 10 | Downstream OMOP analysts have been informed of modifier extension handling decisions and affected data populations | [ ] |
Many FHIR Implementation Guides define modifier extensions specific to their clinical domain. ETL pipelines consuming data from systems implementing these IGs must understand and register those profile-specific extensions. The FHIR Extension Registry is the authoritative index of published extensions. Key IGs to review for modifier extension usage include:
Modifier extension URLs may change across IG versions. An extension that was a regular extension in one version may become a modifier extension in a later version, or vice versa. The FHIR specification's versioning and maturity guidance addresses how breaking changes to extensions should be managed. ETL pipelines consuming data from systems that update their IG versions must:
When consuming FHIR data via the Bulk Data Access API (FHIR $export operations), resources arrive as NDJSON files. The volume of data in bulk exports may create operational pressure to skip per-resource inspection, but the FHIR specification imposes no exception for bulk data. ETL pipelines operating on bulk FHIR exports must apply modifier extension detection to every resource in every NDJSON line.
The presence of a modifier extension is not an indication of a data quality problem in the source FHIR system. Modifier extensions are a legitimate, specified FHIR mechanism for communicating important clinical context that the standard resource structure cannot express. The FHIR specification explicitly provides for their use in circumstances where standard elements are insufficient. Treating modifier extensions as anomalies to be filtered without inspection is the incorrect response — and is precisely the behavior the specification prohibits.
NOTE: The correct framing: a modifier extension is a signal that the source system is communicating something clinically important. The ETL's responsibility is to understand that signal, apply the appropriate disposition, and document the decision — not to eliminate the signal.
| Principle | Implication for FHIR-to-OMOP ETL |
|---|---|
modifierExtension is a distinct, named element — not a subtype of extension |
ETL code must check for modifierExtension explicitly. Generically discarding all extension data without distinguishing the element name bypasses this critical mechanism. |
| Modifier extensions can appear at the resource root and on any backbone element | A two-level detection strategy is required: check the resource root, then check every backbone element within the resource. |
| An unrecognized modifier extension MUST result in non-standard handling | Silent pass-through of unrecognized modifier extensions is non-compliant with the FHIR specification. Quarantine is the correct default for unknown URLs. |
| Common clinical scenarios affected include negation, family history, do-not-use contacts, reliability qualifiers, participant exclusion, and NLP-derived negation | Each scenario has a distinct OMOP disposition. ETL registries must capture the full range of scenarios for each source system and IG. |
| Modifier extensions operate independently of native FHIR status and verification elements | Filtering on status='entered-in-error' and verificationStatus='refuted' is necessary but not sufficient. Modifier extension inspection is a separate, parallel requirement. |
| Handling decisions must be documented and communicated | Modifier extension dispositions must be captured in ETL specifications and surfaced to OMOP analysts so that downstream research can account for the transformations applied. |