diff --git a/src/lib/core/random.c b/src/lib/core/random.c
index 994230c540afde7c94bf196c65b6c4a99ed8e135..621f462181610a7edc68e947a7d86966edc93c12 100644
--- a/src/lib/core/random.c
+++ b/src/lib/core/random.c
@@ -148,6 +148,15 @@ xoshiro_random(void)
 	return result;
 }
 
+void
+xoshiro_srand(uint64_t *seed)
+{
+	state[0] = seed[0];
+	state[1] = seed[1];
+	state[2] = seed[2];
+	state[3] = seed[3];
+}
+
 const char *
 xoshiro_state_str(void)
 {
diff --git a/src/lib/core/random.h b/src/lib/core/random.h
index 9108eab58cd97ae7324ac88e61226e33383e41fe..66ef70f2f225bb8fb30c5396b3fab142f7f621bf 100644
--- a/src/lib/core/random.h
+++ b/src/lib/core/random.h
@@ -60,6 +60,14 @@ real_random(void);
 uint64_t
 xoshiro_random(void);
 
+/**
+ * Sets the `seed` for a new sequence of pseudo-random integers to be returned
+ * by xoshiro_random(). These sequences are repeatable by calling xoshiro_srand
+ * with the same seed value.
+ */
+void
+xoshiro_srand(uint64_t *seed);
+
 const char *
 xoshiro_state_str(void);
 
diff --git a/src/lib/salad/light.h b/src/lib/salad/light.h
index 61c800aaf21650010efb08e2d90fde669d75f35b..94f53d2e2184512f4c3015d19ead9f5c254d6ec1 100644
--- a/src/lib/salad/light.h
+++ b/src/lib/salad/light.h
@@ -845,6 +845,15 @@ LIGHT(grow)(struct LIGHT(common) *ht)
 {
 	assert(!matras_is_read_view_created(ht->view));
 	assert(ht->empty_slot == LIGHT(end));
+	/*
+	 * The number UINT32_MAX has a special meaning (see LIGHT(end)), hence
+	 * it can not be used as a record identifier. Given that the table is
+	 * enlarged by 8 records (see LIGHT_GROW_INCREMENT), the maximum table
+	 * size is limited by (2^32)-8 records.
+	 */
+	if ((size_t)ht->table_size + LIGHT_GROW_INCREMENT >= UINT32_MAX)
+		return -1;
+
 	uint32_t new_slot;
 	struct LIGHT(record) *new_record = (struct LIGHT(record) *)
 		matras_alloc_range(ht->mtable, &new_slot, LIGHT_GROW_INCREMENT);
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 03e3a6d9f3683655d88b359524d4d7e6a5d7fc88..27b52768e203b77f5252ef2d3c2f0942acc1a63a 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -161,8 +161,8 @@ create_unit_test(PREFIX rtree_multidim
                  LIBRARIES salad small
 )
 create_unit_test(PREFIX light
-                 SOURCES light.cc
-                 LIBRARIES small
+                 SOURCES light.cc core_test_utils.c
+                 LIBRARIES core small
 )
 create_unit_test(PREFIX light_view
                  SOURCES light_view.c
diff --git a/test/unit/light.cc b/test/unit/light.cc
index a0d829b27579ac5027cd3c2a92e374376e45ed19..521c6cf1e2db235571c4057d1472c7d5c66ab44c 100644
--- a/test/unit/light.cc
+++ b/test/unit/light.cc
@@ -4,6 +4,7 @@
 #include <inttypes.h>
 #include <vector>
 #include <time.h>
+#include <core/random.h>
 
 #include "unit.h"
 
@@ -350,16 +351,72 @@ slot_in_big_table_test()
 	footer();
 }
 
+/**
+ * Insert nearly 2^32 records into the hash table.
+ */
+static void
+max_capacity_test()
+{
+	/*
+	 * XXX: The test is disabled, because it requires 64 GB of RAM.
+	 */
+	return;
+
+	header();
+
+	/* The maximum number of records that can be stored in the table. */
+	const size_t data_count = (size_t)UINT32_MAX + 1 - LIGHT_GROW_INCREMENT;
+
+	struct light_core ht;
+	light_create(&ht, 0, light_extent_size, my_light_alloc, my_light_free,
+		     &extents_count, NULL);
+
+	uint64_t seed[4];
+	random_bytes((char *)seed, sizeof(seed));
+
+	/* Test light_insert(). */
+	xoshiro_srand(seed);
+	for (size_t i = 0; i < data_count; i++) {
+		hash_value_t val = xoshiro_random();
+		hash_t id = light_insert(&ht, hash(val), val);
+		fail_if(id == light_end);
+		if ((i & 0xfffff) == 0)
+			printf("%f%%\n", i * 100.0 / data_count);
+	}
+	/* Try to exceed the maximum capacity. */
+	hash_value_t val = xoshiro_random();
+	hash_t id = light_insert(&ht, hash(val), val);
+	fail_if(id != light_end);
+
+	/* Test light_find(). */
+	xoshiro_srand(seed);
+	for (size_t i = 0; i < data_count; i++) {
+		hash_value_t val = xoshiro_random();
+		hash_t id = light_find(&ht, hash(val), val);
+		fail_if(id == light_end);
+		if ((i & 0xfffff) == 0)
+			printf("%f%%\n", i * 100.0 / data_count);
+	}
+
+	light_destroy(&ht);
+
+	footer();
+}
+
 int
 main(int, const char**)
 {
-	srand(time(0));
+	random_init();
+
 	simple_test();
 	collision_test();
 	iterator_test();
 	iterator_freeze_check();
 	slot_in_big_table_test();
+	max_capacity_test();
 
 	if (extents_count != 0)
 		fail("memory leak!", "true");
+
+	random_free();
 }