diff --git a/src/service/client/mod.rs b/src/service/client/mod.rs
index cc8d52d1af12a1c5e5e74f309622cdd6e2d26405..03b0a14252e7775a46f72b73ff522e89fcd9bd35 100644
--- a/src/service/client/mod.rs
+++ b/src/service/client/mod.rs
@@ -18,9 +18,7 @@ pub struct Service {
 impl crate::Service for Service {
 	fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 		let config = &args.server.config;
-		let resolver = args
-			.get_service::<resolver::Service>("resolver")
-			.expect("resolver must be built prior to client");
+		let resolver = args.require_service::<resolver::Service>("resolver");
 
 		Ok(Arc::new(Self {
 			default: base(config)
diff --git a/src/service/service.rs b/src/service/service.rs
index 99b8723a0ebbe92b19e1068784413851c1a40a25..863b955b533d76cc75acda6f124ad95e6e6f6f29 100644
--- a/src/service/service.rs
+++ b/src/service/service.rs
@@ -1,7 +1,7 @@
 use std::{any::Any, collections::BTreeMap, fmt::Write, sync::Arc};
 
 use async_trait::async_trait;
-use conduit::{utils::string::split_once_infallible, Result, Server};
+use conduit::{err, error::inspect_log, utils::string::split_once_infallible, Err, Result, Server};
 use database::Database;
 
 #[async_trait]
@@ -44,9 +44,26 @@ pub(crate) struct Args<'a> {
 pub(crate) type MapVal = (Arc<dyn Service>, Arc<dyn Any + Send + Sync>);
 
 impl Args<'_> {
-	pub(crate) fn get_service<T: Any + Send + Sync>(&self, name: &str) -> Option<Arc<T>> {
-		get::<T>(self.service, name)
+	pub(crate) fn require_service<T: Any + Send + Sync>(&self, name: &str) -> Arc<T> {
+		self.try_get_service::<T>(name)
+			.inspect_err(inspect_log)
+			.expect("Failure to reference service required by another service.")
 	}
+
+	pub(crate) fn try_get_service<T: Any + Send + Sync>(&self, name: &str) -> Result<Arc<T>> {
+		try_get::<T>(self.service, name)
+	}
+}
+
+pub(crate) fn try_get<T: Any + Send + Sync>(map: &Map, name: &str) -> Result<Arc<T>> {
+	map.get(name).map_or_else(
+		|| Err!("Service {name:?} does not exist or has not been built yet."),
+		|(_, s)| {
+			s.clone()
+				.downcast::<T>()
+				.map_err(|_| err!("Service {name:?} must be correctly downcast."))
+		},
+	)
 }
 
 pub(crate) fn get<T: Any + Send + Sync>(map: &Map, name: &str) -> Option<Arc<T>> {
diff --git a/src/service/services.rs b/src/service/services.rs
index d0f74e13ae4e3b9571c6ded98cfbe796f1a21c38..136059cdc3ee3f22afa090c17dff5706c66283a7 100644
--- a/src/service/services.rs
+++ b/src/service/services.rs
@@ -173,5 +173,17 @@ fn interrupt(&self) {
 		}
 	}
 
-	pub fn get<T: Any + Send + Sync>(&self, name: &str) -> Option<Arc<T>> { service::get::<T>(&self.service, name) }
+	pub fn try_get<T>(&self, name: &str) -> Result<Arc<T>>
+	where
+		T: Any + Send + Sync,
+	{
+		service::try_get::<T>(&self.service, name)
+	}
+
+	pub fn get<T>(&self, name: &str) -> Option<Arc<T>>
+	where
+		T: Any + Send + Sync,
+	{
+		service::get::<T>(&self.service, name)
+	}
 }