diff --git a/repos/base/src/lib/base/child.cc b/repos/base/src/lib/base/child.cc
index cc8daf4ee0..c16d43a6de 100644
--- a/repos/base/src/lib/base/child.cc
+++ b/repos/base/src/lib/base/child.cc
@@ -533,8 +533,17 @@ void Child::session_response(Server::Id id, Session_response response)
 
 			case Parent::SESSION_CLOSED:
 				session.phase = Session_state::CLOSED;
+
+				/*
+				 * If the client exists, reflect the response to the client
+				 * via the 'closed_callback'. If the client has vanished,
+				 * i.e., if the close request was issued by ourself while
+				 * killing a child, we drop the session state immediately.
+				 */
 				if (session.closed_callback)
 					session.closed_callback->session_closed(session);
+				else
+					_revert_quota_and_destroy(session);
 				break;
 
 			case Parent::INVALID_ARGS:
diff --git a/repos/os/run/init.run b/repos/os/run/init.run
index e0de4e040c..57aaa063f1 100644
--- a/repos/os/run/init.run
+++ b/repos/os/run/init.run
@@ -92,6 +92,12 @@ append config {
 
 			<message string="routing to custom log service"/>
 
+			<!-- We let the client manually create a LOG session in addition
+			     to its env LOG session. So there are two sessions at the
+			     server, one initiated by init and one initiated by the
+			     child. Both cases trigger distinct code paths at child-
+			     destruction time. -->
+
 			<init_config version="chained log services">
 				<report ids="yes" requested="yes" provided="yes"/>
 				<parent-provides>
@@ -121,7 +127,10 @@ append config {
 				<start name="client">
 					<binary name="dummy"/>
 					<resource name="RAM" quantum="1M"/>
-					<config> <log string="client started"/> </config>
+					<config>
+						<log string="client started"/>
+						<create_log_connections count="1"/>
+					</config>
 					<route>
 						<service name="LOG"> <child name="indirect_server"/> </service>
 						<any-service> <parent/> </any-service>
@@ -177,7 +186,10 @@ append config {
 				<start name="client">
 					<binary name="dummy"/>
 					<resource name="RAM" quantum="1M"/>
-					<config> <log string="client started"/> </config>
+					<config>
+						<log string="client started"/>
+						<create_log_connections count="1"/>
+					</config>
 					<route>
 						<service name="LOG"> <child name="indirect_server"/> </service>
 						<any-service> <parent/> </any-service>
@@ -199,6 +211,44 @@ append config {
 			</expect_init_state>
 			<sleep ms="100"/>
 
+			<!-- Kill the client and validate that all session states are freed -->
+
+			<init_config version="client removed">
+				<report ids="yes" requested="yes" provided="yes"/>
+				<parent-provides>
+					<service name="ROM"/>
+					<service name="RAM"/>
+					<service name="CPU"/>
+					<service name="PD"/>
+					<service name="LOG"/>
+				</parent-provides>
+				<start name="server">
+					<binary name="dummy"/>
+					<resource name="RAM" quantum="1M"/>
+					<provides> <service name="LOG"/> </provides>
+					<config> <log_service/> </config>
+					<route> <any-service> <parent/> </any-service> </route>
+				</start>
+				<start name="indirect_server">
+					<binary name="dummy"/>
+					<resource name="RAM" quantum="1M"/>
+					<provides> <service name="LOG"/> </provides>
+					<config> <log_service/> </config>
+					<route> <any-service> <parent/> </any-service> </route>
+				</start>
+			</init_config>
+			<sleep ms="150"/>
+			<expect_init_state>
+				<node name="child">
+					<attribute name="name" value="indirect_server"/>
+					<node name="provided">
+						<not>
+							<node name="session"/>
+						</not>
+					</node>
+				</node>
+			</expect_init_state>
+
 
 			<message string="test changing provided services"/>
 
diff --git a/repos/os/src/test/init/main.cc b/repos/os/src/test/init/main.cc
index 83f6c1319e..162fc9a4de 100644
--- a/repos/os/src/test/init/main.cc
+++ b/repos/os/src/test/init/main.cc
@@ -91,6 +91,9 @@ static inline bool Test::xml_matches(Xml_node expected, Xml_node node)
 
 			matches = matches && at_least_one_sub_node_matches;
 		}
+
+		if (condition.type() == "not")
+			matches = matches && !xml_matches(condition, node);
 	});
 	return matches;
 }