technology

The File That Says You're Covered

A forty-year-old format, a law that froze it, and the date convention that quietly uninsures people

Sathyan··19 min read
An enrollment file moving between an employer, a broker, and an insurer, with one member record silently losing its coverage span along the way

You start a new job on a Monday. Somebody in HR hands you a form, or more likely a link, and you spend eleven minutes choosing between plans you don't fully understand. You pick one. You add your spouse. You close the tab.

Nothing visible happens after that.

Three weeks later you walk into a pharmacy to pick up something routine, and the person behind the counter says the words that mean your afternoon is about to go badly: it's coming back as not covered.

You are covered. You chose the plan, the premium is coming out of your paycheque, the card is in your wallet. Somewhere between that eleven minutes and this counter, a file moved from one company's computer to another company's computer, and something in it was wrong in a way that nobody noticed and nothing alerted on.

This article is about that file.

The five parts before this one built software to handle it. This one is about what it actually is — for anyone who has never seen one, and who has been reasonably assuming that in 2026 health insurance enrollment moves over an API.

It's a Text File

Not a database replica. Not a queue, not a webhook, not a GraphQL endpoint. A text file, frequently dropped onto an SFTP server, frequently on a schedule measured in days.

It's called an 834 — formally, the ANSI X12 834 Benefit Enrollment and Maintenance transaction. When an employer tells an insurer who works there and what they've signed up for, this is the shape that message takes.

Here's one line from one:

INS*Y*18*021*28*A***FT~

That's a person. Specifically, it's the beginning of a member record, and every one of those little fields means something fixed:

PositionValueMeaning
INS01YYes, this person is the subscriber (rather than a dependent)
INS0218Relationship code — 18 is "self"
INS03021Maintenance type — 021 is "addition", a new enrollment
INS0428Maintenance reason — 28 is "initial enrollment"
INS05ABenefit status — active
INS08FTEmployment status — full time

The * separates fields. The ~ ends the segment. Position three means maintenance type and position four means the reason for it, always, in every 834 ever written, because a committee decided that and wrote it down.

A full file is a few hundred of these stacked up, wrapped in an envelope that says who sent it and who it's for. Three hundred members might be four thousand lines.

Every element has a position, every position has a meaning, and the meanings were fixed by a standards committee before a lot of the people maintaining these systems were born.

Why It Looks Like That

The instinctive engineering reaction to an 834 is that somebody did a bad job.

They didn't. X12 — the standard family this belongs to — comes out of the late 1970s and early 1980s, and EDI, Electronic Data Interchange, was the thing that replaced posting paper forms between companies. It was designed for leased lines and magnetic tape, in an era when transmission was billed by the character and storage was genuinely scarce.

Under those constraints, INS*Y*18*021*28*A***FT~ is a superb piece of engineering. It's dense, unambiguous, machine-parseable in a single pass, and it carries no wasted byte. Compare it to the JSON you'd write for the same information and you'd spend four times the characters saying the same thing, most of them repeating field names you already knew.

The format is optimally designed for constraints that stopped existing decades ago.

That's the honest version. It isn't a story about incompetence, and treating it as one is the fastest way to misunderstand everything that follows. It's a story about something excellent outliving its era — and the reasons it outlived its era have almost nothing to do with technology.

Why Nobody Just Replaced It

The format is not a legacy choice that a series of CTOs kept failing to modernise. It's law.

The Health Insurance Portability and Accountability Act — HIPAA, which most people know only as the thing that makes clinics ask you to sign a privacy form — did something else in a section nobody reads. It mandated standard electronic transactions for healthcare administration, and it named the standards. Enrollment is the 834. Claims are the 837. Payment remittance is the 835. Eligibility questions and answers are the 270 and 271.

If you exchange these transactions electronically as a covered entity, you use the mandated formats. Not "should", not "unless you have something better". The specific version in force has been updated over the years, deliberately and slowly, through rulemaking.

Where this is written down. HIPAA's Administrative Simplification provisions (Public Law 104-191, Title II Subtitle F) directed the adoption of these standards; the standards themselves live in 45 CFR Part 162, subparts I and K through R.

TransactionSubpartSections
Health care claims (837)K§§ 162.1101–1102
Eligibility for a health plan (270/271)L§§ 162.1201–1203
Enrollment and disenrollment (834)O§§ 162.1501–1502
EFT and remittance advice (835)P§§ 162.1601–1603

"Why don't they just use an API?" has an answer, and the answer is a statute.

That changes what kind of problem this is. A team that decides to replace their internal format can do it in a quarter. Nobody can replace this one, because it isn't theirs. It belongs to a regulatory process, and the reason that process moves slowly is that every payer, every clearinghouse, every hospital billing system, and every state Medicaid agency in the country would have to move at the same time.

The format is frozen. What isn't frozen is what people do inside it.

The Guides That Break Everything

The standard says what's allowed. It's permissive by design — hundreds of pages of optional segments, alternative code sets, and elements that may or may not appear depending on circumstance.

So every payer publishes a companion guide: a document saying what they actually want. Which optional segments they require. Which code values they honour and which they ignore. Where they expect the plan identifier to live, given that the standard offers more than one plausible home for it. What they'll silently discard.

Hundreds of payers. Hundreds of companion guides. Each one a PDF, each versioned on its own schedule, each perfectly legitimate.

This is where the difficulty actually lives, and it's invisible from outside. Two files can both be flawlessly valid 834s and mean different things, because they were written against different guides. A system that reads one correctly can misread the other while reporting complete success.

The standard makes the file parseable. The companion guide decides whether it means anything.

It also explains something about building software here that's easy to get wrong. There's no version of this platform that gets "written once" and then just runs. The variance isn't a transitional problem to be cleaned up — it's a permanent property of the domain, arriving from hundreds of independent organisations who all have defensible reasons for their choices. Anything built here either absorbs that variance as data, or it hardcodes it and becomes the slowest-moving thing in the company.

"But Isn't Healthcare Moving to FHIR?"

Anyone who's touched a health-tech product in the last decade is thinking it, so let's deal with it.

FHIR — Fast Healthcare Interoperability Resources — is the modern one. JSON over REST, resource-oriented, genuinely pleasant to work with. It's real, it's mandated in its own right, and CMS interoperability rules require payers to expose patient-facing APIs built on it.

HL7 v2 is the other one you'll meet, and it predates even that. Pipe-delimited messages, also from the 1980s, moving clinical events between systems inside a hospital — a patient admitted, a lab result returned, a bed assigned.

None of these replaced each other. They do different jobs.

FormatCarriesLives
X12 (834, 837, 835, 270/271)Administrative and financial — enrollment, claims, payment, eligibilityBetween employers, payers, providers
HL7 v2Clinical events — admissions, orders, resultsBetween systems inside a hospital
FHIRClinical and administrative data over APIsPatient apps, payer-to-payer exchange

A payer runs all three simultaneously, for different purposes, with different teams. FHIR arriving didn't retire the 834 any more than REST arriving retired SQL — they're different layers of the same building.

The formats don't compete. They accumulate.

"But FHIR can do enrollment"

It can, and this is the fair objection. FHIR has a Coverage resource. It has Patient. It has EnrollmentRequest and EnrollmentResponse. On paper you could express everything an 834 carries.

In practice almost nobody runs enrollment that way, for three reasons that have nothing to do with the quality of the specification. The mandated transaction is still X12, so a FHIR-based enrollment would be an extra pipe rather than a replacement. The trading-partner plumbing — the SFTP drops, the acknowledgement transactions, the decades of operational runbooks — is all X12 shaped. And FHIR's financial and administrative resources are markedly less mature and less widely implemented than its clinical ones, because the clinical side is where the attention and the mandates went first.

There is one place FHIR is genuinely displacing an X12 transaction, and the mechanism is stranger than it first looks. Prior authorization has historically run on the X12 278. CMS's Interoperability and Prior Authorization rule now requires impacted payers — Medicare Advantage plans, state Medicaid and CHIP programmes, and Exchange issuers among them — to run four FHIR APIs by January 2027, one of them for prior authorization, with the Da Vinci implementation guide describing how.

The rule arrived in two halves, and the order was deliberate. The part that reaches patients directly landed first: since January 2026, impacted payers have had to decide expedited prior authorization requests within seventy-two hours and standard ones within seven calendar days. The plumbing that makes those decisions cheap to ask for comes a year after that. CMS put the obligation before the infrastructure, which is one reliable way to get infrastructure built.

HIPAA still names the 278, and the regulation adopting it was never withdrawn. What CMS did instead was say it will not enforce against payers who build an all-FHIR prior authorization API and skip the 278 entirely.

The mandate didn't move. The enforcement did.

That's a narrower and more interesting thing than "FHIR won". It's a regulator routing around its own rule because rewriting it would take longer than the problem can wait — and it's the clearest signal available that the boundary between these formats is political rather than technical.

It hasn't moved under enrollment, and there is no rule in flight that moves it there.

Where this is written down. CMS Interoperability and Prior Authorization Final Rule, CMS-0057-F, published February 2024. The four required APIs and the recommended implementation guides are listed on CMS's APIs and standards page, including the enforcement position on the X12 278.

The part that matters more

FHIR has profiles and implementation guides. US Core constrains the base resources for general US use. CARIN constrains them for consumer-facing payer data. Da Vinci constrains them for payer-provider workflows. Each payer then publishes its own guide on top, saying which optional elements it populates, which extensions it defines, which value sets it honours.

That is the companion guide problem, in JSON.

Better syntax moves the variance. It does not remove it.

Two payers can both serve perfectly valid FHIR, conforming to the same base spec, and disagree about what a coverage period means at its boundaries — for exactly the reasons two 834s can. That kind of disagreement is semantic, and it survives translation into any format you like. No syntax decides on your behalf what a date means.

Where this is written down. Profiling is part of the FHIR specification itself (HL7 FHIR — Profiling). The three guides named here are US Core, the US-realm base; CARIN IG for Blue Button, for consumer-directed payer data; and the Da Vinci family, an HL7 FHIR Accelerator covering payer-provider workflows. Da Vinci's guides build on US Core rather than replacing it — layers, not alternatives.

The Path Nobody Owns

The file doesn't go directly from your employer to your insurer, either.

Every hop can transform the data, and each participant validates only its own hop · Click chart to expand

A TPA is a third-party administrator, the company an employer hires to run benefits for them. A PBM is a pharmacy benefit manager, which handles the drug side separately from the medical side. Both are entirely ordinary, and both mean the enrollment information gets read, re-expressed, and re-sent at least once on its way.

Each participant validates its own hop. The broker checks that the employer's file is well-formed. The payer checks that the broker's file is well-formed. Everyone is doing their job correctly and nobody is checking the whole path, because there is no party whose job that is. The employer thinks they enrolled you. The payer thinks they enrolled whoever the file described.

Those are different statements, and the gap between them is where people fall.

How Forty-Seven People Lose Coverage on a Tuesday

Now the specific failure this whole series has been circling, and it's small enough to be genuinely infuriating.

Coverage has a start date and an end date. The start is unambiguous. The end is not.

The 834 standard's termination date is the last day the person is covered. Inclusive. If it says December 31st, the person is covered through December 31st.

Plenty of systems — reasonably, and following a convention that's standard elsewhere in software — store an end date as the first day the person is no longer covered. Exclusive. In those systems, coverage through December 31st is stored as January 1st.

Both conventions are defensible. Both are common. Both appear in production systems handling millions of people. And converting between them is one line of code that adds or subtracts a day.

Here's what happens when it's missing, and then what happens when it's applied twice.

An HR system sends a file. For a member enrolled for January it sets the effective date to January 1st and the termination date to January 31st — the last covered day, exactly as the standard says.

A receiving system that stores end dates as exclusive needs February 1st to mean the same thing. If it takes January 31st at face value, it has quietly recorded thirty days of coverage instead of thirty-one, and the member is uninsured on the last day of the month. That's the mild version. It shows up as a single denied claim on an unlucky date, and it's almost never traced back to the file.

The severe version comes from the same conversion being applied in the wrong direction, or applied by two systems in a row that each assume the other didn't. Subtract where you should have added and January 1st through January 31st becomes a span that ends before it begins. Have the sender pre-convert and the receiver convert again, and the boundaries can land on the same day.

A span whose end is not after its start covers nothing. Not thirty days, not one day — zero.

The member exists. The record processed. Every field is populated. The span is empty.

The file was syntactically perfect. Every segment well-formed. Every date a real date. Every code a valid code from the correct code set. There was nothing to throw an exception about, because the failure isn't in the syntax — it's in the meaning, and meaning has no exception type.

Three hundred and twelve members went in. Three hundred and twelve members processed. Forty-seven of them came out holding a coverage span that covers nothing at all.

Why Nobody Notices

Every property that would normally catch this is absent.

No error is raised, so no alert fires and no dashboard turns red. The counts reconcile — 312 in, 312 out, and every reconciliation report in the pipeline agrees the file processed completely. The feedback loop is weeks long, because enrollment is asynchronous by nature; nothing tests whether coverage works until somebody uses it.

And the person affected has no visibility at all. There is no screen you can log into that shows you the coverage span your insurer is holding for you, expressed the way their system stores it. You have a card. The card looks the same either way.

It surfaces at a counter.

Somebody tries to fill a prescription and it rejects. The pharmacy staff — who deal with this constantly and are usually the most competent people in the chain — suggest calling the number on the card. The call centre says the system shows no active coverage for that date. The member says that's impossible, because they enrolled in January and it's February.

Somebody eventually opens a ticket. Eventually, someone looks at the file. Eventually, a correction is sent.

Every step of that is somebody doing their job properly. The whole sequence still takes days, and it starts with a person standing at a counter deciding whether to pay full price for something they need.

By the time it reaches anyone who could recognise it as a data problem, it has been reclassified as a customer service problem, which is a different queue with different people and a different fix.

What It Costs

The chain is short and it compounds.

A prescription rejects, so the medication is delayed or abandoned — and for a maintenance drug, abandonment is a clinical event and not just an inconvenience. A claim denies, so the provider bills the patient directly, at rates negotiated for uninsured people rather than the plan's rates. A visit gets postponed until coverage is "sorted out."

Then the correction arrives, and this is the part worth dwelling on: fixing the record does not undo what happened while the record was wrong.

The retroactive correction restores the coverage span. It does not automatically unwind the denied claim, or the balance the provider already billed, or the payment the member already made at full price, or the medication they didn't take for eleven days. Each of those has its own reversal path, on its own timeline, requiring somebody to pursue it.

The record becomes recoverable. The consequences do not.

That asymmetry runs through everything in this series. A system can be perfectly reversible and still do permanent harm, because the world acted on the wrong answer while it stood.

Which Makes It a Data Problem

Nothing here needs new medicine. Nothing here needs new policy, or a new standard, or a better format. The information was correct when it left the employer, and it was correct in the file. It stopped being correct when one system read another system's date convention through its own assumptions, and no part of the path was built to notice.

What that needs is a system where semantic failure is as loud as syntactic failure. Where "312 processed, 47 meaningless" is a state the platform can express, rather than a thing that has to be discovered at a pharmacy counter three weeks later.

That's what the last five parts have been about, underneath the vocabulary they used. A canonical model, so the meaning of a coverage span is defined in exactly one place instead of being re-decided by every system that touches it. A parser that isolates a bad record instead of losing the file. A rule layer that writes down what it checked, including the checks that passed, so "we verified this" is a claim with evidence behind it.

None of that is exotic. It's ordinary engineering discipline, applied to a domain where the cost of skipping it lands on somebody who never knew the system existed.

The Forty-Seven

They've been in every part of this series and they haven't been fixed yet.

I can now say precisely what fixing them requires, which is further than this series has got before.

The conversion between the standard's inclusive termination date and an exclusive internal one has to happen in exactly one place — one function, one line, applied on the way in and never again. Anything that lets that conversion happen in two places lets the two disagree. A span that covers zero days has to be a rule the system enforces and records, rather than a shape it can silently hold. And where a payer's companion guide differs on the convention, that difference has to live as configuration the system reads, not as an assumption baked into whichever engineer implemented that payer first.

All three of those exist in the platform now. What hasn't happened is the thing that closes the loop: running a file shaped like that one through the whole pipeline and watching it fail loudly, on purpose, with a message a human can act on.

That's what the next part is for.

Somebody is standing at a pharmacy counter right now being told they aren't covered, and they are. The file was valid. Every system in the chain reported success.

That sentence should be alarming, and in most of this industry it still isn't.

Enjoyed this?

Get new articles delivered to your inbox. No spam, unsubscribe anytime.

Related Articles

More from Narchol