A ghost fulfilment is a parcel that ships for an order that no longer exists. The customer cancelled, the refund was issued, and the box went out anyway. You pay forward freight, return freight and handling on revenue you already gave back — and because the order shows as cancelled everywhere you look, the shipment never appears in any report you review.
This is not a warehouse discipline problem. It is a distributed systems problem wearing a logistics costume, and treating it as the former is why it keeps happening.
The Race Condition
Between a customer clicking cancel and a parcel leaving the dock, several independent systems must agree. They do not share a clock, a transaction, or in most cases a direct connection:
- The storefront records the cancellation and refunds.
- A webhook fires to the fulfilment integration — or a scheduled job polls for changes on a 15–30 minute cycle.
- The 3PL's WMS receives the update and attempts to halt the pick.
- The pick list was printed earlier and is already on the floor. Paper does not receive webhooks.
- The label is generated, the courier manifest is closed, the parcel is on the truck.
Anywhere the update arrives after step 4, the physical process wins. The window is small — often minutes — but it is exactly the window in which most cancellations occur, because buyers cancel almost immediately after ordering.
Polling Guarantees the Failure
If your fulfilment integration polls on a 15-minute cycle, you have accepted an average 7.5-minute blind spot and a worst case of 15. That is a design decision, not bad luck. The same cancellation that arrives at minute 1 of a cycle is caught; at minute 14 it is not.
Webhooks close most of that gap but introduce their own failure modes, which is where most teams stop investigating and where the remaining losses live.
The Webhook Failures That Cause Ghost Shipments
Kepler's webhook-watchdog and webhook-idempotency engines separate the failures worth alerting on, because they need different fixes:
WEBHOOK_DELIVERY_LATENCY_SLA_BREACH_HIGH— the event arrived, but late. This is the direct ghost-shipment cause and the one most teams never measure, because a late webhook still looks like a successful webhook in the logs.WEBHOOK_RETRY_EXHAUSTION_STALLED_WARNING— delivery failed repeatedly and the platform gave up. The cancellation never arrived at all. Silent by construction: nothing in your system knows about a message it never received.WEBHOOK_HMAC_SIGNATURE_DROPPED_CRITICALandWEBHOOK_HMAC_SIGNATURE_INVALID_CRITICAL— events rejected at the gate. Correct security behaviour, and a total loss of the event unless something is watching rejection counts.WEBHOOK_DUPLICATE_IDEMPOTENCY_KEY_COLLISION_CRITICAL— the same event processed twice. Platforms guarantee at-least-once delivery, not exactly-once, so duplicates are normal traffic and your handler must be idempotent.WEBHOOK_CLOCK_DRIFT_EXCEEDED_WARNING— sender and receiver disagree about time, which breaks both signature validation windows and any ordering logic built on timestamps.
The load-bearing insight: a webhook endpoint returning 200 tells you the message was accepted, not that it arrived in time to stop anything. Latency is the metric that matters here, and almost nobody graphs it.
A Worked Example
Illustrative model. Inputs are stated so you can substitute your own; these are not measured results or an industry benchmark.
2,000 orders/day, a 4% cancellation rate, and a 15-minute polling cycle where 20% of cancellations land inside the blind spot after the pick list has printed:
- Cancellations/day: 80 — of which ~16 fall in the window
- If half of those are already picked and shipped: 8 ghost shipments/day
- Forward ₹95 + return ₹110 + handling ₹25 = ₹230 each → ₹1,840/day
Roughly ₹55,000 a month on these inputs, none of it visible in a cancelled-orders report, plus the units out of stock for a fortnight while they travel in both directions.
The Controls, In Order of Effectiveness
- A dispatch-time status check. The single highest-value control: before a parcel is manifested, re-query order status from the source of truth rather than trusting the pick list. This closes the race regardless of how the cancellation propagated, and it is the only control that works when the webhook never arrived at all.
- Event-driven cancellation, not polling. Subscribe to the cancellation event directly. This shrinks the window; the dispatch check closes what remains.
- Monitor webhook latency and retry exhaustion, not just endpoint uptime. Alert on the p99 delivery lag and on any retry exhaustion at all.
- Idempotent handlers keyed on event ID. Assume duplicates. A cancellation processed twice must be harmless.
- Reconcile daily. Every AWB carrying freight, anti-joined against orders with a valid non-cancelled status. This catches what the first four missed and is the audit that tells you whether the controls are actually working.
The Cost Recovery Side
Once a ghost shipment has happened, two costs are recoverable and usually are not pursued. If the parcel was cancelled before courier pickup but still carries a freight charge, that is dead freight and is disputable on the courier invoice. And if the buyer refuses delivery, the unit returns — so it belongs in your RTO reconciliation rather than being written off as a mystery.
The wider reconciliation, including how dead freight surfaces in a courier invoice audit: The Ultimate Guide to E-Commerce Profit Leak Audits.
Related Guides
- Setting Up Shopify Webhooks for Real-Time Order Management: A Step-by-Step Tutorial
- The Ultimate Guide to E-Commerce Profit Leak Audits: Recovering Courier Overcharges & Hidden Fee Creep
- Multi-Warehouse Inventory Desync: Preventing Safety Stock Oversell Disasters
⚡ Try This Verification Rule in the Sandbox
Test sample payloads in our zero-dependency interactive explorer.
Open Free API Sandbox →🧮 Interactive Profit Leak Estimator
LIVE ESTIMATOREstimate your monthly financial loss from courier weight creep, dead freight, and gateway fee drift:
Based on standard 10.5% volumetric weight creep & 1.2% cancellation dead freight across industry benchmarks.
Trap Commerce Operations Discrepancies Automatically
Run a free instant diagnostic on your data or grab our verified operations templates on Gumroad: