Back to all posts
Integration|6 min read

The Most Expensive EDI Exception Is the One That Never Arrives

Dan @ Tare Labs·August 4, 2026

Mapping a 315 is easy. Any competent integration contractor can stand one up in an afternoon: pull the segments, translate the event codes, write to the shipment record, send an ack. It demos well. It passes UAT with the ten sample files the carrier gave you.

Then it goes to production, and six months later someone in customer service is on the phone explaining why a container the system says is on the water has been sitting on a terminal stack in Long Beach since the 14th.

The map wasn't wrong. The map was fine. What nobody built was the part that decides whether the message you just received is believable, and what to do when no message comes at all.

The happy path is a day of work. The exception path is the project.

Ocean status is messier than most people expect going in, because a 315 is not a system of record. It's a claim. A carrier is telling you what they believe happened, assembled from terminal feeds, vessel schedules, and internal milestones that update on their own cadence. Your integration treats that claim as fact and writes it straight to your shipment.

Here are the failure modes I keep finding when I get handed an integration to clean up.

Failure mode 1: Silence

This is the expensive one, and it's the one almost nobody instruments.

Every other failure mode throws something. A malformed segment fails the map. A bad envelope fails the ack. A duplicate throws a constraint violation. Somebody, somewhere, gets an error.

Absence throws nothing. The container sits at "vessel departed" and the record looks healthy: it has a status, it has a timestamp, no alert fired. It just stopped moving eleven days ago, and your system has no opinion about that, because you built it to react to messages and no message came.

The fix is conceptually simple and organizationally hard: you need expected-next-event logic. If a box loaded on a vessel with a 12-day transit, you should be looking for a discharge event in a window, and the absence of one past that window is itself an event. That means modeling the lifecycle, not just the message. It means a scheduled job, a tolerance per lane or per carrier, and a queue that someone actually watches.

Most teams skip it because it isn't in the mapping spec. It's the single highest-ROI thing you can add.

Failure mode 2: Events that arrive out of order

EDI is not a stream with guaranteed ordering. You will receive a discharge before the load event that preceded it. You'll get a gate-out that predates the gate-in. Retransmissions arrive days after the original, carrying old timestamps.

If your integration is last-write-wins (and most are, because that's the default behavior when you map status to a field), the timeline silently corrupts. Your shipment now says the container came off a vessel it never got on.

The correction is to stop treating status as a field and start treating it as an event log. Append events with their reported timestamps, derive current status from the log, and let arrival order be irrelevant. That's a bigger design change than a mapping tweak, which is exactly why it doesn't happen in the initial build.

Failure mode 3: Contradiction between sources

The carrier's 315 says the container gated out Tuesday. The terminal feed says it's still on the stack. Your drayage provider's portal says something else entirely.

None of these systems are lying. They're updating on different cadences from different sensors. The problem is that nobody defined precedence, so the effective rule becomes "whichever source called us most recently wins," or worse, "whoever complains loudest."

You need a written hierarchy: which source is authoritative for which event type, how stale a source has to be before you downgrade it, and what happens when two authoritative sources disagree. It's a half-page document that almost nobody writes, and its absence generates a permanent tax on the operations team.

Failure mode 4: Codes used loosely

The 315 status codes are standardized in the sense that the spec defines them. They are not standardized in the sense that carriers use them the same way.

The seams show up in predictable places. Estimated timestamps sitting in the same structure as actuals, distinguished by a qualifier nobody validated. Vessel departure meaning "left the berth" to one carrier and "cleared the pilot station" to another. Rail events reported inconsistently or not at all on inland moves. Timezone conventions that vary by trading partner and occasionally by message.

Every one of these produces a map that succeeds and data that's wrong. No error, no alert, no queue: just numbers that are slightly off in a direction nobody notices until they're used for a KPI, a customer commitment, or a detention dispute.

Carrier-specific normalization isn't optional. It's the actual work.

Failure mode 5: References that don't join

The message is perfectly valid. It just doesn't match anything you have. Booking number instead of your shipment ID, container number with a different check-digit convention, a BL that was amended after you filed it.

These land in a suspense queue. The queue gets built during implementation, and then it doesn't get an owner, because owning it wasn't in anyone's job description at go-live. Six months later there are 4,000 items in it and everyone has agreed not to look.

Why this keeps happening

None of the above is an EDI problem. EDI is doing what it was designed to do.

It happens because integration projects get scoped by the mapping spec, and the mapping spec describes the happy path. The exception path is where the requirements are ambiguous, where the business rules have to be decided rather than documented, and where the work continues past go-live. It's the part that doesn't fit neatly in a statement of work, so it gets deferred, and deferred work in integrations doesn't come back. It just becomes the operations team's manual process.

The tell is easy to spot. If your status integration has no answer to "what happens when nothing happens," you don't have exception handling. You have a mapper.

What to do instead

Build the happy path in a day. Then spend the real budget on:

• Expected-next-event monitoring, with tolerances per carrier and lane, so silence becomes a detectable condition.

• An append-only event log as the source of truth, with current status derived rather than overwritten.

• A written source hierarchy defining precedence and staleness thresholds.

• Per-carrier normalization for codes, estimate-vs-actual qualifiers, and timezone handling, validated against real production traffic rather than sample files.

• A named owner for the exception queue, with a target for how long an item can sit in it.

That last one is not a technical control, and it's the one that decides whether any of the rest survives the first quarter.

Tare Labs builds integration and AI systems for logistics and supply chain teams. If you're staring at a status feed you don't trust, reach out. We do free 30-minute sessions: no pitch, just a direct look at where your status data is breaking down.

Want to talk about this?

Reach out at dan@tarelabs.com or book a free consultation.