diff --git a/Cargo.lock b/Cargo.lock
index 15be459..c8642fc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1086,6 +1086,7 @@ name = "nzr-api"
 version = "0.1.0"
 dependencies = [
  "figment",
+ "log",
  "serde",
  "tarpc",
  "tokio",
diff --git a/api/Cargo.toml b/api/Cargo.toml
index 38700d1..415b6a2 100644
--- a/api/Cargo.toml
+++ b/api/Cargo.toml
@@ -11,4 +11,5 @@ serde = { version = "1", features = ["derive"] }
 tarpc = { version = "0.31", features = ["tokio1", "unix"] }
 tokio = { version = "1.0", features = ["macros"] }
 uuid = "1.2.2"
-trust-dns-proto = { version = "0.22.0", features = ["serde-config"] }
\ No newline at end of file
+trust-dns-proto = { version = "0.22.0", features = ["serde-config"] }
+log = "0.4.17"
\ No newline at end of file
diff --git a/api/src/net/cidr.rs b/api/src/net/cidr.rs
index 1c49638..d6b71a6 100644
--- a/api/src/net/cidr.rs
+++ b/api/src/net/cidr.rs
@@ -162,6 +162,11 @@ impl CidrV4 {
     /// This method is not affected by the object's host address.
     pub fn make_ip(&self, host_bits: u32) -> Result<Ipv4Addr, Error> {
         if host_bits > !self.netmask {
+            log::error!(
+                "Host bits too large ({:032b} vs {:032b})",
+                !self.netmask,
+                host_bits
+            );
             Err(Error::HostBitsTooLarge)
         } else {
             Ok((host_bits | u32::from(self.network().addr)).into())
diff --git a/nzrd/src/ctrl/net.rs b/nzrd/src/ctrl/net.rs
index 38d4d00..57eeab6 100644
--- a/nzrd/src/ctrl/net.rs
+++ b/nzrd/src/ctrl/net.rs
@@ -140,14 +140,18 @@ impl Entity<Subnet> {
     ) -> Result<Entity<Lease>, Box<dyn std::error::Error>> {
         let tree = self.db.open_tree(self.lease_tree())?;
         let max_lease = match tree.last()? {
-            Some(lease) => u32::from_be_bytes(lease.0[..4].try_into().unwrap()),
+            Some(lease) => {
+                // XXX: this is overkill, but a lazy hack for now
+                u32::from_be_bytes(lease.0[..4].try_into().unwrap())
+                    & !u32::from(self.model.network.netmask())
+            }
             None => self.model.start_bytes(),
         };
         let new_ip = self
             .model
             .network
             .make_ip(max_lease + 1)
-            .map_err(|_| SubnetError::SubnetFull)?;
+            .map_err(SubnetError::BadHost)?;
         let lease_data = Lease {
             subnet: String::from_utf8_lossy(&self.key).to_string(),
             ipv4_addr: CidrV4::new(new_ip, self.model.network.cidr()),