MedVertical

BlogFHIR Operations

Terminology Drift: The Silent Killer of FHIR Data Quality

Your FHIR data was valid when it was created. It may not be valid today. Terminology drift is a common — and often under-monitored — source of FHIR data quality failures.

Abstract terminology drift visual showing code systems, value set expansion, and validation changes over time
André Sheydin
André Sheydin
Founder, MedVertical7 min read
fhirterminologydata-qualitydriftvaluesetcodesystemsnomed-ctloinc

In the previous article, I asked whether you can answer three questions about your FHIR data. The first — "Is your production data valid right now?" — is the one most teams get wrong for a specific, predictable reason. This article is about that reason.

Here is a failure mode that can hit production systems, is rarely caught in advance, and is surprisingly easy to understand once someone names it:

Your FHIR data was valid when it was created. It may no longer be valid today. Nothing in your system changed.

This is terminology drift — and it's one of the most underestimated sources of ongoing data quality failures in FHIR implementations.

What terminology binding actually means

When you define a FHIR profile, you bind elements to ValueSets. In many profiles, a Condition.code may be constrained to SNOMED CT or ICD-10-GM. A MedicationRequest.status uses a required HL7-defined value set. An Observation.code for a lab result is often constrained to LOINC.

These bindings are what make FHIR data meaningful rather than just structured. They're also what makes FHIR data fragile in a specific, predictable way.

A binding is a contract: "this value must be a member of this ValueSet, resolved against this terminology source." But the terminology source isn't frozen. It's a living system maintained by an external body — HL7, NLM, SNOMED International, NUCC, Regenstrief — on its own release schedule, with its own governance processes.

When the terminology changes, your binding contract changes with it. Your data does not.

The four ways terminology drifts

1. Code retirement

A code that was valid in SNOMED CT release 2024-09 may be retired in release 2025-03. The concept was split into two more specific codes, or merged into a parent, or deprecated in favor of a post-coordinated expression.

Resources created with the retired code may have been valid at the time of creation. Depending on validation policy, they may now fail validation or move from pass to warning/error — not because the resource changed, but because the terminology moved.

This is particularly acute for SNOMED CT, whose International Edition now has a monthly release cadence. Organizations that cache terminology snapshots locally — or pin their validator to an older release — may not discover the drift until they update their toolchain.

2. ValueSet expansion changes

A ValueSet may be a fixed list of codes, or it may be a rule-based definition against a terminology source. "All SNOMED CT concepts that are descendants of 'disorder of the cardiovascular system'" is a valid kind of ValueSet definition. Its expansion — the actual set of codes it matches — can change every time the SNOMED hierarchy is updated.

An observation code that was included in last year's expansion may not be included in this year's. A binding that was satisfied before a terminology release may fail afterward.

Worse: ValueSet expansion is often done lazily. Many implementations expand once, cache the result, and never re-expand. The cached expansion becomes stale. Validation against it produces false positives — resources flagged as failing a binding they would actually satisfy against the current expansion, or vice versa.

3. CodeSystem version changes

Some terminologies version their code meanings explicitly. LOINC is moving from a historically twice-yearly cadence toward monthly releases, targeting March 2027. ICD-10-GM — the German clinical modification used in ISiK and MII profiles — publishes annual updates. Other terminology systems have their own release schedules and governance models.

When a CodeSystem publishes a new version, the validator needs to resolve codes against the right version. If the version isn't pinned, different validation runs may resolve against different CodeSystem versions and produce different results for the same resource.

This is not a theoretical concern. It produces real inconsistencies in validation reports — runs that contradict each other without any data change, because the underlying terminology reference shifted between runs.

4. Terminology server behavior changes

Many FHIR implementations delegate terminology resolution to an external service — a FHIR terminology server that handles $validate-code and $expand operations. These servers are themselves software, and they update.

A new release of a terminology server may fix a bug in code resolution — and in doing so, produce different results for edge cases your system relied on. A server configuration change may alter expansion behavior. A network timeout may cause a validation to fall through to a cached result that's out of date.

None of these necessarily produces an obvious error. They produce quiet shifts in your validation baseline.

Why this is hard to catch

The standard approach to FHIR validation — run the HL7 validator in CI, check for errors before merging — does not catch terminology drift. It catches structural problems and profile violations at a point in time.

The gap is that CI runs when code changes. Terminology changes independently of your code. Between two successful CI runs — where nothing in your codebase changed — your conformance status may have shifted because a terminology server updated, a ValueSet expansion changed, or a CodeSystem published a new release.

The only way to catch this is to run validation continuously against live data, independently of your pipeline, with a mechanism to detect when results change between runs.

That's drift detection: not "does this resource fail validation?" but "did this resource's validation status change since the last run — and if so, why?"

What a terminology drift incident looks like

A composite example of how this surfaces in practice:

A hospital running ISiK Stage 3 validation runs their FHIR validation in their CI pipeline. Everything passes. They deploy.

Three weeks later, a terminology release lands. Their terminology server auto-updates. The update changes the status of several codes that appear in their patient condition records — codes that were accepted before, now deprecated, inactive, or outside the current expansion.

Their next CI run passes. The CI pipeline doesn't run against live patient data. It runs against test fixtures, which don't include the affected codes because nobody added those edge cases to the test suite.

The affected codes sit in production, failing or warning under the partner's terminology validation policy. A partner clinic consuming the data via its own ISiK integration starts rejecting resources. The hospital finds out when the partner's integration team files a support ticket.

The investigation takes two weeks. The fix — either updating the codes or pinning the terminology version — takes another week. The total window of silent failure: five weeks.

This is a realistic incident pattern for organizations that validate episodically rather than continuously.

The fix is not just better tooling — it's treating terminology as infrastructure

The instinct when hearing this problem is: "we need a better CI pipeline." Add more test fixtures. Add a terminology validation step. Add a scheduled job that runs validation nightly.

These help at the margins. They don't address the structural issue, which is specific to terminology: your validation environment is not stable between runs.

The fix requires managing terminology the same way you manage code dependencies — with explicit versioning, lockfiles, and change detection:

  • Pin your terminology snapshots. Don't resolve codes against "the current version" of an external terminology service. Lock to a specific release. Know exactly which SNOMED CT release, which ICD-10-GM year, which LOINC version your validation runs against.
  • Track when terminology sources update. If your terminology server auto-updates, treat each update as a potential breaking change that warrants a re-validation of your production data.
  • Validate continuously against live data — not just test fixtures. Terminology drift affects the data already in production, not just new data coming in.
  • Compare runs, not just results. A single validation run tells you the current state. Comparing two runs tells you whether the state changed — and if so, whether the change came from the data or from the terminology.

What to do right now

If you're operating a FHIR server and haven't audited your terminology dependencies recently, start here:

  • Identify your terminology sources. Which CodeSystems and ValueSets do your profiles bind to? Are they externally maintained? What's their release cadence?
  • Check your terminology server's update policy. Does it auto-update? Does it pin to a specific release? When did it last update?
  • Run a validation scan against your current live data — not your test fixtures — and check whether the results match your last CI run.
  • Establish a baseline. The only way to know if conformance has drifted is to have something to compare against.

Terminology drift is not an exotic edge case. It's a normal risk in any FHIR system that doesn't actively manage its terminology dependencies. The question isn't only whether your data has drifted — it's whether you can see when it happens.

André Sheydin

About the author

André Sheydin

André is the founder of MedVertical and a product and design lead based in Cologne. He has spent more than 25 years shaping digital products, platforms, and design systems across complex domains, including healthcare, pharma, automotive, and SaaS. His work focuses on turning technical requirements into product structures that teams can actually build and operate.

Records

See the validation layer behind the article.

Records deploys adjacent to your FHIR server and validates your data continuously, with profile context, terminology resolution, and reproducible evidence.