Repository navigation
Description
What is failing
The RoutingGrain routing pool on the portal silos saturates briefly: 64 route dispatches in flight at once, with the oldest leg growing from ~6s to ~29s over a 30-second burst, and (on activation 5bdfaaf2) up to 55 legs queued waiting for a pool slot. Dispatches spanned Store, Hosting, and Essentials destinations. Both portal pods were hit simultaneously, so this was a single correlated event, not one sick pod.
Probable cause
By the log line's own gauge legend, this reads as transient downstream I/O slowness, not a slot leak: routing pool subscribing was ~0 on both activations, so legs were past their subscribe prologue and waiting downstream; oldest legs were seconds old (not minutes, which would indicate a leaked slot); and both episode series drained without recurrence. Confidence: medium — the evidence supports "the silo absorbed a burst", but the samples alone cannot say which downstream (Store/Hosting/Essentials dispatch targets) was slow. A secondary, higher-confidence defect: the log line embeds the per-activation id (e.g. 5bdfaaf2#3) in a form the fingerprint masking rule does not normalize, so every activation spawns a separate LogIncident — ~30 near-identical back-pressure incidents exist in the Admin partition from the last three days alone. That masking gap is flooding the incident feed.
Impact
From the numbers: 6 log lines over 30 seconds on 2026-09-22 12:43, self-resolving, no delivery failures or slot leaks observed. Real but brief routing latency portal-wide; the larger ongoing cost is incident-feed noise from the fingerprinting gap. Given the burst recurred repeatedly over the past days, the slow downstream deserves investigation before it becomes a sustained degradation.
Where to look
MeshWeaver.Hosting.Orleans.RoutingGrain— the[ROUTE] Routing back-pressurelog site and its routing-pool slot accounting; the message's own pointers reference issues RoutingGrain dispatch slots saturate with legs head-of-line blocked behind one shared-cache destination while the second pod starves on load #5009 (per-channel head-of-line) and RoutingGrain dispatch pool saturates repeatedly on portal silos; slots held through unbounded ThreadPool wait and episode-stamp splitting floods incidents #5018 (pool gauge semantics).- Fingerprinting/masking rule for this category: normalize the activation-id + episode stamp (
{id}#{n} started {time}) so one routing-pool episode doesn't fan out into a fresh incident per activation. - For the slow downstream: correlate the 12:43:08–12:43:37Z window with Store/Hosting/Essentials pod-hub delivery logs on both pods (
memex-portal-deployment-5c89c7f5f9-sddb5,memex-portal-deployment-7cc85f47c-nm2qp).
Evidence
| Fingerprint | 0ed431eabd045ec8 |
| Category | MeshWeaver.Hosting.Orleans.RoutingGrain |
| Severity | Critical |
| Namespace | memex-cloud |
| Pods | memex-portal-deployment-5c89c7f5f9-sddb5, memex-portal-deployment-7cc85f47c-nm2qp |
| Occurrences | 6 |
| First seen | 2026-09-22 12:43:08Z |
| Last seen | 2026-09-22 12:43:37Z |
| Routing | not determined — no configured route matches the category MeshWeaver.Hosting.Orleans.RoutingGrain. This repository is the configured fallback, not a finding about who owns the fault; the category names the LOGGER, which may not be the subject. |
Recent log lines
2026-09-22 12:43:14Z memex-portal-deployment-7cc85f47c-nm2qp crit: MeshWeaver.Hosting.Orleans.RoutingGrain[0]
[ROUTE] Routing back-pressure [97b1fb3b#5 started 2026-09-22T12:43:14.3250574Z]: 64 route dispatches in flight (reporting threshold 64); ordered channels queued 0 over 0 stream destination(s), deepest per-channel queue 0, routing pool subscribing 0, waiting for a pool slot 0; oldest leg in flight 5783 ms — dispatch → Hosting (delivery s9qOmk7PwkK7zWHqtLrUqQ). Latest dispatch target DeepSign/Credential — the address that happened to cross the threshold, NOT a diagnosis. A slot is held from dispatch until the leg terminates, INCLUDING the unbounded wait for a ThreadPool thread before the leg's own timeouts start, so a CPU-starved silo raises this with nothing stuck. A CHANNEL is (destination, stream), so a deepest queue of 1 or more means legs of the SAME stream are blocked behind one another (head-of-line within one channel); 0 means nothing is waiting on anything, so read it as load. Many channels over FEW destinations is a multiplexer hub draining in parallel, which is load too — before issue #5009 those legs shared one channel and read as head-of-line. 🚨 THE TWO POOL GAUGES ANSWER DIFFERENT QUESTIONS AND ONLY ONE SEES THE WAIT NAMED ABOVE — issue #5018. 'subscribing' counts legs inside their SUBSCRIBE PROLOGUE only, so a leg still waiting for a ThreadPool thread and a leg already past its subscribe BOTH read 0 there; 'waiting for a pool slot' is the gauge that sees the pre-subscribe wait. High while subscribing is below the pool's cap is a THREAD shortage; both near zero means the legs are past their subscribe and the wait is downstream I/O. 🚨 READ THE OLDEST LEG FIRST: it is the only load-vs-leak discriminator available from a SINGLE line — every leg young is load the silo is absorbing, one leg minutes old is a slot that never came back and the label names it — whereas the episode stamp below needs a SECOND line to say anything. 🚨 Deepest is sampled AT THE CROSSING, so like the in-flight count it is partly…[truncated]
2026-09-22 12:43:18Z memex-portal-deployment-5c89c7f5f9-sddb5 crit: MeshWeaver.Hosting.Orleans.RoutingGrain[0]
[ROUTE] Routing back-pressure [5bdfaaf2#1 started 2026-09-22T12:43:18.3039751Z]: 64 route dispatches in flight (reporting threshold 64); ordered channels queued 8 over 3 stream destination(s), deepest per-channel queue 11, routing pool subscribing 0, waiting for a pool slot 8; oldest leg in flight 9787 ms — dispatch → rbuergi/_Install/AppleMusic (delivery NZoogGL0_UaWkrZiGjK6lA). Latest dispatch target portal/egXML8v7Y8GjHurnb8KTfloONWmGqcGbVAtCvfjeDWk — the address that happened to cross the threshold, NOT a diagnosis. A slot is held from dispatch until the leg terminates, INCLUDING the unbounded wait for a ThreadPool thread before the leg's own timeouts start, so a CPU-starved silo raises this with nothing stuck. A CHANNEL is (destination, stream), so a deepest queue of 1 or more means legs of the SAME stream are blocked behind one another (head-of-line within one channel); 0 means nothing is waiting on anything, so read it as load. Many channels over FEW destinations is a multiplexer hub draining in parallel, which is load too — before issue #5009 those legs shared one channel and read as head-of-line. 🚨 THE TWO POOL GAUGES ANSWER DIFFERENT QUESTIONS AND ONLY ONE SEES THE WAIT NAMED ABOVE — issue #5018. 'subscribing' counts legs inside their SUBSCRIBE PROLOGUE only, so a leg still waiting for a ThreadPool thread and a leg already past its subscribe BOTH read 0 there; 'waiting for a pool slot' is the gauge that sees the pre-subscribe wait. High while subscribing is below the pool's cap is a THREAD shortage; both near zero means the legs are past their subscribe and the wait is downstream I/O. 🚨 READ THE OLDEST LEG FIRST: it is the only load-vs-leak discriminator available from a SINGLE line — every leg young is load the silo is absorbing, one leg minutes old is a slot that never came back and the label names it — whereas the episode stamp below needs a SECOND line to say anything. 🚨 Deepest is sampled AT TH…[truncated]
2026-09-22 12:43:22Z memex-portal-deployment-5c89c7f5f9-sddb5 crit: MeshWeaver.Hosting.Orleans.RoutingGrain[0]
[ROUTE] Routing back-pressure [5bdfaaf2#2 started 2026-09-22T12:43:22.1915343Z]: 64 route dispatches in flight (reporting threshold 64); ordered channels queued 2 over 2 stream destination(s), deepest per-channel queue 10, routing pool subscribing 0, waiting for a pool slot 1; oldest leg in flight 13675 ms — dispatch → rbuergi/_Install/AppleMusic (delivery NZoogGL0_UaWkrZiGjK6lA). Latest dispatch target cache/okfkP_QznEqGS0e2ZfNrGA — the address that happened to cross the threshold, NOT a diagnosis. A slot is held from dispatch until the leg terminates, INCLUDING the unbounded wait for a ThreadPool thread before the leg's own timeouts start, so a CPU-starved silo raises this with nothing stuck. A CHANNEL is (destination, stream), so a deepest queue of 1 or more means legs of the SAME stream are blocked behind one another (head-of-line within one channel); 0 means nothing is waiting on anything, so read it as load. Many channels over FEW destinations is a multiplexer hub draining in parallel, which is load too — before issue #5009 those legs shared one channel and read as head-of-line. 🚨 THE TWO POOL GAUGES ANSWER DIFFERENT QUESTIONS AND ONLY ONE SEES THE WAIT NAMED ABOVE — issue #5018. 'subscribing' counts legs inside their SUBSCRIBE PROLOGUE only, so a leg still waiting for a ThreadPool thread and a leg already past its subscribe BOTH read 0 there; 'waiting for a pool slot' is the gauge that sees the pre-subscribe wait. High while subscribing is below the pool's cap is a THREAD shortage; both near zero means the legs are past their subscribe and the wait is downstream I/O. 🚨 READ THE OLDEST LEG FIRST: it is the only load-vs-leak discriminator available from a SINGLE line — every leg young is load the silo is absorbing, one leg minutes old is a slot that never came back and the label names it — whereas the episode stamp below needs a SECOND line to say anything. 🚨 Deepest is sampled AT THE CROSSING, so like t…[truncated]
2026-09-22 12:43:34Z memex-portal-deployment-5c89c7f5f9-sddb5 crit: MeshWeaver.Hosting.Orleans.RoutingGrain[0]
[ROUTE] Routing back-pressure [5bdfaaf2#3 started 2026-09-22T12:43:34.3598640Z]: 64 route dispatches in flight (reporting threshold 64); ordered channels queued 0 over 0 stream destination(s), deepest per-channel queue 0, routing pool subscribing 0, waiting for a pool slot 55; oldest leg in flight 19430 ms — dispatch → Essentials (delivery Pn6_iDorbki17T2JrWmxSA). Latest dispatch target v-ramavakita/_Install/ICloud — the address that happened to cross the threshold, NOT a diagnosis. A slot is held from dispatch until the leg terminates, INCLUDING the unbounded wait for a ThreadPool thread before the leg's own timeouts start, so a CPU-starved silo raises this with nothing stuck. A CHANNEL is (destination, stream), so a deepest queue of 1 or more means legs of the SAME stream are blocked behind one another (head-of-line within one channel); 0 means nothing is waiting on anything, so read it as load. Many channels over FEW destinations is a multiplexer hub draining in parallel, which is load too — before issue #5009 those legs shared one channel and read as head-of-line. 🚨 THE TWO POOL GAUGES ANSWER DIFFERENT QUESTIONS AND ONLY ONE SEES THE WAIT NAMED ABOVE — issue #5018. 'subscribing' counts legs inside their SUBSCRIBE PROLOGUE only, so a leg still waiting for a ThreadPool thread and a leg already past its subscribe BOTH read 0 there; 'waiting for a pool slot' is the gauge that sees the pre-subscribe wait. High while subscribing is below the pool's cap is a THREAD shortage; both near zero means the legs are past their subscribe and the wait is downstream I/O. 🚨 READ THE OLDEST LEG FIRST: it is the only load-vs-leak discriminator available from a SINGLE line — every leg young is load the silo is absorbing, one leg minutes old is a slot that never came back and the label names it — whereas the episode stamp below needs a SECOND line to say anything. 🚨 Deepest is sampled AT THE CROSSING, so like the in-flight coun…[truncated]
2026-09-22 12:43:37Z memex-portal-deployment-7cc85f47c-nm2qp crit: MeshWeaver.Hosting.Orleans.RoutingGrain[0]
[ROUTE] Routing back-pressure [97b1fb3b#6 started 2026-09-22T12:43:37.6418961Z]: 64 route dispatches in flight (reporting threshold 64); ordered channels queued 0 over 0 stream destination(s), deepest per-channel queue 0, routing pool subscribing 1, waiting for a pool slot 0; oldest leg in flight 28927 ms — dispatch → Essentials (delivery O9YpsPxhck2DAZDWFyHYEw). Latest dispatch target Admin/_Build/Systemorph.MeshWeaver.Crm — the address that happened to cross the threshold, NOT a diagnosis. A slot is held from dispatch until the leg terminates, INCLUDING the unbounded wait for a ThreadPool thread before the leg's own timeouts start, so a CPU-starved silo raises this with nothing stuck. A CHANNEL is (destination, stream), so a deepest queue of 1 or more means legs of the SAME stream are blocked behind one another (head-of-line within one channel); 0 means nothing is waiting on anything, so read it as load. Many channels over FEW destinations is a multiplexer hub draining in parallel, which is load too — before issue #5009 those legs shared one channel and read as head-of-line. 🚨 THE TWO POOL GAUGES ANSWER DIFFERENT QUESTIONS AND ONLY ONE SEES THE WAIT NAMED ABOVE — issue #5018. 'subscribing' counts legs inside their SUBSCRIBE PROLOGUE only, so a leg still waiting for a ThreadPool thread and a leg already past its subscribe BOTH read 0 there; 'waiting for a pool slot' is the gauge that sees the pre-subscribe wait. High while subscribing is below the pool's cap is a THREAD shortage; both near zero means the legs are past their subscribe and the wait is downstream I/O. 🚨 READ THE OLDEST LEG FIRST: it is the only load-vs-leak discriminator available from a SINGLE line — every leg young is load the silo is absorbing, one leg minutes old is a slot that never came back and the label names it — whereas the episode stamp below needs a SECOND line to say anything. 🚨 Deepest is sampled AT THE CROSSING, so like the in-fl…[truncated]
Re-addressed by the current identity function: this incident inherited e4a97855ab595beb (Systemorph/MeshWeaver.Plugins#1796). Those nodes are superseded and will not fold, file or comment again.
Opened automatically from Admin/_LogIncident/0ed431eabd045ec8. Recurrences are folded into this issue rather than opening new ones.
Activity
rbuergi commentedon Sep 22, 2026
Closing as a duplicate of #5118 — the fingerprint-split flood.
Why this is a duplicate. Every one of these comes from the same log site —
[ROUTE] Routing back-pressure, categoryMeshWeaver.Hosting.Orleans.RoutingGrain— split into one issue per grain activation. The 8-hex activation id survived normalization (a0e2984b→a0e2{n}b):HexBlobrequired 16+ chars, andNumber()then masked only the digit-run preceded by a digit, leaving a per-activation residue in the hash.Measured over 101 verbatim bursts drawn from 29 issues, covering 42 activation ids: the old parser yields 41 distinct fingerprints, the current parser yields 1.
The fix is already merged in MeshWeaver.Plugins — #2165 (
MixedHexId), #2167, #2168 (positional episode/target masking) and #2218 (the portal re-parses raw samples, instead of hashing text a stale watcher already masked).It is not live yet. The control instance is sealed on an older set because the Plugins Portal image rebuild workflow fails at its GitHub App token step —
actions: writeis not granted to the installation — so core's rebuild is never dispatched. Until that is granted, new split issues will keep arriving, and an issue whose activation is still alive may reopen here.Not closed by this. The underlying routing condition — cache-destination head-of-line blocking versus ThreadPool starvation — is a real defect and stays open in #5118. The normaliser itself is tracked in #5270 and #5271.
rbuergi commentedon Sep 22, 2026
Why this is its own issue, and what stops the next one — posted on each RoutingGrain back-pressure incident issue filed 2026-09-22; not a disposition of this one.
This incident's fingerprint was split from its siblings by two values the incident normaliser did not mask — the delivery id and a single-segment destination in the line's
oldest leg in flight … — dispatch → <address> (delivery <id>)field — not by the episode stamp, which was already masked. Fixed in Systemorph/MeshWeaver.Plugins#2286 (merged 2026-09-22T21:46Z asb922f070fc): over the 146 back-pressure samples quoted in the open core issues (43 filed fingerprints), the identity now yields 3 (one per leg kind, plus the pre-#5151 wording). It reaches production with the portal roll; existing incidents re-address onto their successors throughLogIncidentCorpusMigration.What the crossing itself means is a separate question and is not answered by the fix above. A line reading high
waiting for a pool slotwithrouting pool subscribing 0is legs the ThreadPool had not yet run (the pool's cap is 256 and no permit is held — see #5261 (comment)); that starvation root is being investigated separately (family: #5018, #4886). A line with a non-zerodeepest per-channel queueon acache/…destination and an old oldest leg is #5009's falsifier and should be raised there.Disposition stays with triage: a symptom gauge can invert the causal arrow, so this issue's own sample may carry evidence its siblings do not.