nautechsystems/nautilus_trader · error

failed to receive logging sync acknowledgement: {e}

Error message

failed to receive logging sync acknowledgement: {e}

What it means

This error is raised by the logging sync helper in nautilus_common's logger. It sends a LogEvent::Sync over the logging worker channel and blocks on a one-shot acknowledgement channel; if the receiver end (done_rx) returns an error — typically because the sender was dropped, meaning the logging thread shut down or the ack was never sent — it wraps the RecvError in this anyhow error. It indicates the logging worker is no longer alive or responsive.

Source

Thrown at crates/common/src/logging/logger.rs:1319

        }

        let Some(tx) = LOGGER_TX.get() else {
            anyhow::bail!("Logging is running without a published sender");
        };

        sync_sender_to_disk(tx)
    }
}

#[cfg(not(all(feature = "simulation", madsim)))]
fn sync_sender_to_disk(tx: &std::sync::mpsc::Sender<LogEvent>) -> anyhow::Result<()> {
    let (done_tx, done_rx) = std::sync::mpsc::channel();
    tx.send(LogEvent::Sync(done_tx))
        .map_err(|e| anyhow::anyhow!("failed to request logging sync: {e}"))?;

    done_rx
        .recv()
        .map_err(|e| anyhow::anyhow!("failed to receive logging sync acknowledgement: {e}"))?
}

/// Logs a message with the given level, color, and component.
pub fn log<T: AsRef<str>>(level: LogLevel, color: LogColor, component: Ustr, message: T) {
    let color = Value::from(color as u8);

    match level {
        LogLevel::Off => {}
        LogLevel::Trace => {
            log::trace!(component = component.to_value(), color = color; "{}", message.as_ref());
        }
        LogLevel::Debug => {
            log::debug!(component = component.to_value(), color = color; "{}", message.as_ref());
        }
        LogLevel::Info => {
            log::info!(component = component.to_value(), color = color; "{}", message.as_ref());
        }
        LogLevel::Warning => {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the logging worker thread is running and has not been shut down before calling the logging sync function.
  2. Check for panics in the logging worker that would drop done_tx without sending an acknowledgement.
  3. Re-initialize the logging system (recreate the logger/worker) if it was torn down, then retry the sync.
  4. Guard teardown ordering so no component calls log sync after the logging system is dropped.

Example fix

// before: syncing after teardown
logging_shutdown();
logging_sync()?; // fails: receiver dropped
// after
logging_sync()?;
logging_shutdown();
Defensive patterns

Strategy: try-catch

Try / catch

match logging_sync() {
    Ok(()) => {},
    Err(e) if e.to_string().contains("failed to receive logging sync acknowledgement") => {
        // logging worker is down; re-init or skip flush during teardown
        eprintln!("logging worker unavailable: {e}");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling the logging sync function after the logging worker thread has been stopped or dropped; the worker panicked before sending the acknowledgement; the LogEvent::Sync was accepted but the worker exited without responding on done_tx.

Common situations: Shutting down or re-initializing the logging system while another thread still tries to flush/sync logs; a panic inside the logging worker; calling sync during process teardown when the channel endpoints were already dropped.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/11a6c3bf184a4b35. Report an issue: GitHub.