We continued the same XRumer series at pass 5/5 after 110 rejected start requests and a controller error had blocked it. Four completed passes stayed in its history. The recovery needed an operator's help, a correction to retry accounting and a normal Stop before the next Remaining pass could run.
This third article in our link building automation series examines the incident on . The useful distinction was between a command XRumer rejected, a command our agent proved it had never sent and a command whose outcome remained uncertain.
- Engine in this case
- XRumer 23.0.9
- Rejected starts
- 110 explicit busy responses
- Actual preparation failures
- 1 in 111 recorded attempts
- Observed recovery
- Same series, four completed passes, current pass 5/5
Why 110 Busy Rejections Did Not Start Pass Five
The fourth pass had reached position 584,397 of 584,397. One worker was still active. Our panel requested run.rest, the command used here to start another pass over Remaining targets, but XRumer returned an explicit negative busy response. The journal eventually contained 110 such rejections.
None of those requests started pass five. Counting requests as passes would have created a history of work that never ran. The series still had four completed passes and a blocked transition. The input reaching its final position also did not establish that the last worker had finished.
Our Full and Remaining pass policy keeps the configured maximum separate from observed execution. In this incident, 5/5 was the intended next ordinal, not a result that could be inferred from a command queue. We needed the negative command receipts to explain why the fifth pass was absent.
The 110 rejections were a failure to advance, not a useful retry target. Once the retained worker was visible, the next investigation concerned readiness and command outcomes. Sending more requests could not explain why that worker remained active.
How One Preparation Failure Exhausted the Wrong Retry Budget
Attempt 111 failed before command dispatch. Our agent recorded phase=preparation_failed and sent=false. This was the first proven preparation failure in that journal.
The server compared the overall attempt number with the preparation-error limit. It therefore treated the previous rejected requests as if they had consumed that budget. One actual preparation failure then appeared to exhaust the allowed retries, and the series stopped behind a generic Windows-agent error.
We changed the accounting to count the journal entries that actually established a preparation failure before sending. Confirmed negative busy receipts no longer consume that budget. The command attempt number remains useful for tracing the sequence, but it cannot serve as a count of one particular failure class.
The old journal could verify the counting error. It could not reveal the precise low-level cause of the single preparation failure: that agent version had not retained the failing stage or exception details. We corrected the demonstrated server defect and added diagnostics for future failures without assigning an unsupported cause to the old one.
How We Decide Whether a Command Can Be Retried
Removing busy responses from the preparation budget was only part of the change. The controller also had to preserve uncertainty. In particular, sent=null must stay distinct from sent=false. An unknown outcome cannot become evidence that nothing was sent.
| Recorded outcome | What the evidence establishes | Next decision |
|---|---|---|
| Confirmed rejected busy | A negative response for the specific command. Excluded from the preparation-failure budget. | Check readiness before another start. Do not record a new pass from this rejection. |
Preparation failed, sent=false | The command was proven unsent. Count the actual preparation failure. | Retry only within the preparation budget while the outcome remains certain. |
Unknown outcome, sent=null | Sending or execution has not been resolved. | Block automatic replay and reconcile the command with engine state. |
| Positive acknowledgment (ACK) | A positive response exists for the command. This is not an unsent preparation failure. | Do not resend it. Check fresh execution state and position movement. |
| Missing journal evidence | The record does not prove that sending never happened. | Block automatic replay. Recover the context and inspect the resulting state. |
These fields and decisions describe our controller. They are not a claim that every XRumer integration exposes the same statuses or that the vendor provides an idempotent start API. The guard prevents our automatic replay when the evidence is insufficient; it does not establish exactly-once posting.
For an operator, the first question is whether the evidence belongs to the command under investigation. A fresh panel observation can help resolve an uncertain result, but a generic running badge cannot identify which request produced it. Keep the intended action attached to its instance and series, then compare the resulting pass with that expectation.
What We Checked Before Continuing the Series
The operator had manually restarted the affected XRumer process. That changed the process identity, so the controller could not safely treat its old binding as current. We checked the replacement process against the intended instance and retained series before further recovery actions.
Verified copies of the working base, configuration, reports and LastURL resume data were available for those actions. We checked the saved position against the current input rather than assuming that an existing LastURL file was sufficient. After the manual restart, its position was 584,395 of 584,397: two records short of the previously observed end.
The retained history still supplied the four completed passes. Starting a new series to remove the error would have discarded that context and made the recovery harder to audit. We continued the existing history instead.
A second XRumer instance on the same host was still running its first pass. It did not need a restart. Keeping process bindings separate, as described in our XRumer automation setup, let us work on the affected instance without restarting its neighbor.
Why We Used a Normal Stop Before Continuing
Continuing from the saved position processed the final two records. The last worker then remained active again. The manual restart had therefore not removed the observed tail-worker problem.
We issued one normal run.stop command to the affected instance. It received a positive acknowledgment. The active-worker count changed from 1 to 0, the position remained at 584,397 of 584,397 and the engine's Others count changed from 546,703 to 546,704. The unresolved tail was recorded among the remaining work.
This Stop was separate from the operator's earlier process restart. We did not force-terminate the process during this recovery action. The observed drain gave us a new final state to preserve, rather than leaving the fourth pass's result frozen before its last worker settled.
We obtained a new verified end-of-file checkpoint and updated the fourth pass's final snapshot for that one additional Others entry. Its notification status and message reference stayed intact. The operator did not delete or rewrite the working bases or reports; XRumer itself made the working-file changes.
A normal Stop was effective in this incident. That observation does not identify why the worker hung or demonstrate that an internal engine defect was fixed. Another blocked transition still needs its own command and state evidence.
How We Confirmed Pass 5/5 Was Running
With the retained history and verified checkpoint, we requested the next Remaining pass. Its first command attempt received a positive acknowledgment. The controller kept the same series, with four completed passes and the current pass numbered 5/5.

The screenshot is evidence of the displayed history, not sufficient evidence of continuing execution. At that screenshot's moment, the separate rate card showed zero. We used a saved MCP observation and subsequent position growth to establish that work was actually progressing.
| Evidence | Recorded result | What it supports |
|---|---|---|
| Saved controller and MCP snapshot, | Four completed passes; pass 5/5; command acknowledged and native command done; fresh posting state with 299 active workers; position 585,585 of 1,123,134. | The intended pass and an active engine observation agree. |
| Subsequent recovery report, same date | Position 585,727 and growing. The report does not retain a separate exact observation time. | The input position advanced beyond the saved snapshot. |
| Historical panel screenshot, same date | Prior pass markers and the fifth Remaining-pass start remain visible. | The panel retained the transition history; this image alone does not prove a live processing rate. |
The four earlier notification records retained their sent status without being sent again. The second instance was not restarted and continued its own first pass. These checks mattered because restoring one run should not create duplicate completion messages or erase another instance's context.
What We Added to the Agent Diagnostics
A generic Windows-agent error was too coarse to explain the next failure. We added stage recording for binding, process and preflight checks, followed by mcp_budget, mcp_preflight, mcp_dispatch and mcp_poll. The record also keeps a safe exception type and source line. It excludes keys and raw HTTP exception text.
The server's corrected accounting applies across instances. The Windows diagnostic update in this incident was installed only for the affected first instance. We did not update every agent or the shared installation package as part of this recovery.
Validation covered 83 local Python tests, 137 tests on server Python 3.11 and 7 Windows MCP checks without sending real test commands to the vendor. Those checks exercised the controller changes. The live Stop, accepted Remaining start and observed position growth provided separate evidence of the actual recovery.
The next operator can now distinguish a failure before dispatch from a failure during polling. That additional context improves the investigation; it cannot reconstruct exception details the older agent never saved.
What We Preserved and What Remains Unproven
The operational result was a continued series with its four completed passes preserved, corrected preparation-error accounting and explicit guards against replaying uncertain commands. Recovery was operator-assisted. It was not an unattended repair of the XRumer engine.
We still do not know the root cause of the hanging worker or the precise exception behind the old preparation failure. Nothing in this case measures ranking gains, indexed backlinks, hours saved or cost per verified link. Those outcomes need their own observations beyond an engine's counters.
For a similar incident, use the command-outcome table before choosing another start. Preserve the series context, then verify the intended pass through fresh state and position movement. The XRumer link building service scope should specify result verification separately from this run-control work.
Request the XRumer Recovery Decision Log
A blank CSV for command evidence, retry decisions and observed recovery state, with an anonymized case note. Submit the form and our team will send the files separately by email.
Thanks. Your request for the XRumer Recovery Decision Log has been received. Our team will review it and send the file separately by email. What happens next →
Sources and Case Scope
This account uses our November 5, 2026 incident report, a verification of the 111-attempt journal, the saved controller and MCP snapshot, checkpoint verification and the original panel screenshot. The later report records position growth without a separate exact time; it is not presented as a simultaneous screenshot reading.
The command-state policy and diagnostics belong to our custom panel. Private host identities, process identifiers, paths and base names are omitted. Request the anonymized case note and recovery log for the evidence summary and decision fields. The first two Journal articles cover the control architecture and pass-series policy.


