spacedriveapp/spacedrive · error · anyhow::Error

File transfer protocol not registered

Error message

File transfer protocol not registered

What it means

PUSH fetches the protocol handler registered under the name "file_transfer" from the NetworkingService's ProtocolRegistry (the canonical handler's protocol_name() returns "file_transfer", core/src/service/network/protocol/file_transfer.rs:1429). None means the registry never received a FileTransferProtocolHandler — networking came up without registering built-in protocols, registration failed, or a custom registry construction omitted it.

Source

Thrown at core/src/ops/files/copy/strategy.rs:366

			name: local_path
				.file_name()
				.unwrap_or_default()
				.to_string_lossy()
				.to_string(),
			size: file_size,
			modified: metadata.modified().ok(),
			is_directory: metadata.is_dir(),
			checksum,
			mime_type: None,
		};

		let networking_guard = &*networking;
		let protocol_registry = networking_guard.protocol_registry();
		let registry_guard = protocol_registry.read().await;

		let file_transfer_handler = registry_guard
			.get_handler("file_transfer")
			.ok_or_else(|| anyhow::anyhow!("File transfer protocol not registered"))?;

		let file_transfer_protocol = file_transfer_handler
			.as_any()
			.downcast_ref::<crate::service::network::protocol::FileTransferProtocolHandler>()
			.ok_or_else(|| anyhow::anyhow!("Invalid file transfer protocol handler"))?;

		let transfer_id = file_transfer_protocol
			.initiate_transfer(
				dest_device_id,
				local_path.to_path_buf(),
				crate::service::network::protocol::TransferMode::TrustedCopy,
			)
			.await?;

		debug!("PUSH transfer initiated with ID: {}", transfer_id);
		ctx.log(format!("PUSH transfer initiated with ID: {}", transfer_id));

		let result = stream_file_data(

View on GitHub (pinned to 6dfeccf211)

Solutions

  1. Check daemon startup logs for protocol registration failures and fix/re-run registration
  2. Ensure NetworkingService initialization registers built-in protocols before any copy job is dispatched
  3. If you construct the ProtocolRegistry yourself, register FileTransferProtocolHandler explicitly
  4. Restart the daemon after fixing init so the registry is repopulated

Example fix

// before
let mut registry = ProtocolRegistry::new(); // no built-ins registered

// after
let mut registry = ProtocolRegistry::new();
registry.register(std::sync::Arc::new(
    crate::service::network::protocol::FileTransferProtocolHandler::new(),
));
Defensive patterns

Strategy: validation

Validate before calling

let networking = ctx.networking_service().ok_or_else(|| anyhow::anyhow!("no networking"))?;
let registry = networking.protocol_registry();
if registry.read().await.get_handler("file_transfer").is_none() {
    return Err(anyhow::anyhow!("file_transfer protocol not registered; networking started without built-ins"));
}

Prevention

When it happens

Trigger: NetworkingService started in a mode that skips built-in protocol registration; init-order bug where the copy job runs before registration completes; test or embedded setup constructing a bare ProtocolRegistry without the file-transfer handler.

Common situations: Custom daemon builds with protocol registration toggled off; startup error during registration swallowed earlier; refactoring that moved registration out of the boot path.

Related errors


AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16). Data as JSON: /api/errors/fe48a59a531b2d6b. Report an issue: GitHub.