ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

Message History

Every message carries the trace of its own journey. When looking for why an INVOIC arrives late or why an ORDERS is rejected, you open the embedded history: list of traversed components, versions, timestamps. The cornerstone of distributed debugging.

Problem

A modern EDI pipeline traverses around 20 components: AS2 gateway, sniffer, parser, validator, enricher, translator, router, ERP adapter, etc. Each has its version, configuration, execution node. When something goes wrong — rejected invoice, abnormal latency, bad translation — you must be able to reconstruct the message's exact path: which components touched it, in what order, at which version, on which node. Without Message History, the investigation turns into a hunt across scattered logs. With it, it is readable at a glance inside the message itself.

Forces

  • Self-documentation. The message carries its own path proof; no need to correlate 20 log files.
  • Auditability. For fiscal flows, proving who touched what is useful during audits.
  • Debugging aid. When a message reproduces a bug, the history points directly to the guilty version.
  • Message bloat. Each component adds ~200 bytes; on 20 components = ~4 KB. Acceptable for typical EDI messages (KB-MB), externalise for very small messages.
  • GDPR. The history can contain personal data (who processed?). Do not expose to partners without masking.

Solution

EIP §551 (Hohpe & Woolf, 2003) defines Message History as a message header that grows with each component traversed. The contract is simple: each component touching the message appends an entry at the end of the list, with at minimum: its name, version, host, timestamp, action performed. It never removes an existing entry. At pipeline end (or in incident), the list is a faithful image of the path.

plaintext topology.txt
┌────────┐   ┌────────┐   ┌────────┐   ┌────────┐
   │ A      │──▶│ B      │──▶│ C      │──▶│ D      │
   └────────┘   └────────┘   └────────┘   └────────┘
       │            │            │            │
       │            │            │            ▼
       │            │            │     append { D, ts, version }
       │            │            ▼     ────────────────────────
       │            │     append { C, ts, version }
       │            ▼     ────────────────────────
       │     append { B, ts, version }
       ▼     ────────────────────────
   append { A, ts, version }
   ────────────────────────

   The message carries a cumulative list; at the end you can read
   who touched it, in what order, when.

EDI implementation

Three concrete uses:

json message-history.json
{
  "messageId": "01HVF8K3X1ABCDE0123456789",
  "messageType": "INVOIC",
  "messageHistory": [
    {
      "component": "as2-gateway",
      "version": "2.4.1",
      "host": "edi-gw-prod-02",
      "ts": "2026-05-14T12:00:00.123Z",
      "action": "received-from-partner",
      "details": { "as2From": "SUPPLIER_GLN", "as2To": "BUYER_GLN" }
    },
    {
      "component": "parser-edifact",
      "version": "1.7.0",
      "host": "edi-parse-prod-05",
      "ts": "2026-05-14T12:00:00.842Z",
      "action": "parsed",
      "details": { "format": "EDIFACT D96A", "sizeBytes": 4218 }
    },
    {
      "component": "validator-schema",
      "version": "1.7.0",
      "host": "edi-valid-prod-03",
      "ts": "2026-05-14T12:00:01.012Z",
      "action": "validated",
      "details": { "rulesPassed": 47, "rulesWarned": 1 }
    },
    {
      "component": "translator-canonical",
      "version": "3.0.2",
      "host": "edi-trans-prod-01",
      "ts": "2026-05-14T12:00:01.247Z",
      "action": "translated-to-canonical"
    },
    {
      "component": "router-outbound",
      "version": "2.1.0",
      "host": "edi-rout-prod-04",
      "ts": "2026-05-14T12:00:01.318Z",
      "action": "routed",
      "details": { "destination": "erp.sap.invoice.in" }
    }
  ]
}
  • CONTRL/997 acknowledgement chain. For each received ack (CONTRL, 997, APERAK), record into the original message's history: "at 12:00:05Z, CONTRL+1 received from partner 5798000000122". The history tells the whole ack cycle.
  • Latency diagnosis. An INVOIC takes 3 minutes to land. The history shows the validator took 2m45 at 12:00:01 — bug or backpressure. Immediate trace, no need to correlate 5 systems.
  • Fiscal audit. "Can you prove this invoice was emitted without modification?" The history lists each transformation and its author; combined with before/after hashes, this is integrity proof.
  • Loop detection. If the same component appears several times (e.g. router-outbound twice), there is a cycle. The pattern detects it automatically.

Articulation with W3C TraceContext

In 2026, you do not write a Message History from scratch; you align with W3C TraceContext (traceparent + tracestate, 2020) so that OpenTelemetry / Jaeger / Tempo / Datadog can correlate traces. Message History serves the business layer (who = which component did what), TraceContext serves the network layer (cross-span correlation). Both coexist in the message's canonical envelope.

Anti-patterns

  • History that overwrites. A component replacing the history instead of enriching it destroys the pattern's value. Append-only, never replaced.
  • No-version history. Tracking "went through validator" without saying which version loses half the debugging value.
  • Too verbose. Including full payload at every step multiplies message size 20×. Keep symbolic, delegate detail to logs.
  • History exposed to partners. The partner does not need your internal details (host names, versions). Strip before external emission.
  • No normalised timestamp. Mixing timezones and formats turns analysis into a nightmare. ISO 8601 UTC everywhere.

Sources

  • Hohpe G., Woolf B. — Enterprise Integration Patterns, Message History (§551). enterpriseintegrationpatterns.com — Message History
  • W3C Trace Context (W3C Recommendation, November 2020). Standard format for traceparent and tracestate, complementing Message History on the network observability side. w3.org/TR/trace-context
  • OpenTelemetry — Specification. Distributed tracing model adopted by every modern tool, compatible with Message History for business metadata. opentelemetry.io/docs/specs
  • UN/EDIFACT — CONTRL and APERAK. The EDIFACT acknowledgement types, whose chain inscribes naturally into Message History.