GraphiteEditor/Graphite · error

Failed to connect to the main process bootstrap server

Error message

Failed to connect to the main process bootstrap server

What it means

Panic in the out-of-process CEF UI host when IpcSender::<EventMessage>::connect fails to connect to the bootstrap IPC server created by the main Graphite process (the address arrives via the HostConfig 'server' argument). ipc-channel connects over a Unix domain socket (Linux/macOS) or named pipe (Windows); connect fails when nothing is listening, the path is stale or wrong, or the sandbox denies connecting.

Source

Thrown at desktop/ui/src/remote/host.rs:29

use crate::frames::sequence::SequenceState;
#[cfg(target_os = "macos")]
use crate::platform::mac;

pub(crate) fn run() {
	// Ignore SIGINT, the controlling process is responsible for shutting down the host
	#[cfg(any(target_os = "linux", target_os = "macos"))]
	unsafe {
		libc::signal(libc::SIGINT, libc::SIG_IGN);
	}

	let args: Vec<String> = std::env::args().collect();
	let config = HostConfig::from_args(&args).expect("CEF host started without a valid host config argument");
	let acceleration_requested = config.acceleration;

	#[cfg(target_os = "macos")]
	mac::spawn_parent_watchdog(config.main_pid);

	let bootstrap = IpcSender::<EventMessage>::connect(config.server.clone()).expect("Failed to connect to the main process bootstrap server");
	let event_sender = Arc::new(Mutex::new(bootstrap));
	let (control_sender, control_receiver) = ipc_channel::ipc::channel::<HostControlMessage>().expect("Failed to create control channel");

	#[cfg(feature = "accelerated_paint")]
	let plane = if acceleration_requested { PlaneSender::from_config(&config, event_sender.clone()) } else { None };
	#[cfg(feature = "accelerated_paint")]
	let acceleration = plane.is_some();
	#[cfg(not(feature = "accelerated_paint"))]
	let acceleration = {
		if acceleration_requested {
			tracing::error!("UI acceleration requested but the accelerated_paint feature is disabled; using software frames");
		}
		false
	};

	event_sender
		.lock()
		.expect("The host message sender cannot be poisoned before threads exist")

View on GitHub (pinned to c507b35645)

Solutions

  1. Check whether the main Graphite process (whose pid is passed in the config) is still alive at the moment of failure
  2. Look for a crash log/stack trace of the main process, since its early death is the usual root cause
  3. Verify both processes run as the same user and no sandbox blocks the local socket
  4. Re-launch the app; if it reproduces, run with logging to capture the main process's startup error

Example fix

// before
let bootstrap = IpcSender::<EventMessage>::connect(config.server.clone()).expect("Failed to connect to the main process bootstrap server");

// after
let bootstrap = IpcSender::<EventMessage>::connect(config.server.clone()).unwrap_or_else(|e| {
	eprintln!("Failed to connect to the main process bootstrap server at {:?}: {e} (is the main process {} still running?)", config.server, config.main_pid);
	std::process::exit(1);
});
Defensive patterns

Strategy: retry

Validate before calling

// Before connecting, check the main process is still alive (pid comes from the host config)
fn main_process_alive(pid: u32) -> bool {
	!std::path::PathBuf::from(format!("/proc/{pid}")).exists() || std::path::Path::new(&format!("/proc/{pid}")).exists()
}

Try / catch

let mut last_err = None;
for _ in 0..5 {
	match IpcSender::<EventMessage>::connect(config.server.clone()) {
		Ok(sender) => return sender,
		Err(e) => {
			last_err = Some(e);
			std::thread::sleep(Duration::from_millis(100)); // main process may still be binding
		}
	}
}
panic!("Failed to connect to the main process bootstrap server after retries: {:?}", last_err);

Prevention

When it happens

Trigger: The main process died or exited between spawning the host process and the host's connect call; a stale socket path passed through the host config; running the host under a sandbox/container that blocks the socket namespace; permission mismatch between the two processes' users.

Common situations: The parent Graphite process crashing at startup right after spawning the UI host; kill -9 of the main process leaving the host to fail connecting; security software blocking local sockets; mismatched builds where the config serialization changed.

Related errors


AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16). Data as JSON: /api/errors/168ede8e602601b3. Report an issue: GitHub.