diff --git a/swh/storage/cassandra/storage.py b/swh/storage/cassandra/storage.py
--- a/swh/storage/cassandra/storage.py
+++ b/swh/storage/cassandra/storage.py
@@ -228,6 +228,7 @@
             if counter >= limit:
                 next_page_token = str(tok)
                 break
+            row_d["ctime"] = row.ctime.replace(tzinfo=datetime.timezone.utc)
             contents.append(Content(**row_d))
 
         assert len(contents) <= limit
@@ -240,7 +241,7 @@
             # matches the argument, from the index table ('content_by_sha1')
             for row in self._content_get_from_hash("sha1", sha1):
                 row_d = row.to_dict()
-                row_d.pop("ctime")
+                row_d["ctime"] = row.ctime.replace(tzinfo=datetime.timezone.utc)
                 content = Content(**row_d)
                 contents_by_sha1[content.sha1] = content
         return [contents_by_sha1.get(sha1) for sha1 in contents]
diff --git a/swh/storage/tests/storage_tests.py b/swh/storage/tests/storage_tests.py
--- a/swh/storage/tests/storage_tests.py
+++ b/swh/storage/tests/storage_tests.py
@@ -605,6 +605,16 @@
 
         assert actual_contents == expected_contents
 
+    def test_content_get_ctime_not_naive(self, swh_storage, sample_data):
+        cont = sample_data.contents[0]
+
+        swh_storage.content_add([cont])
+
+        content = swh_storage.content_get([cont.sha1])[0]
+
+        assert content.ctime is not None
+        assert content.ctime.tzinfo is not None
+
     def test_content_get_missing_sha1(self, swh_storage, sample_data):
         cont1, cont2 = sample_data.contents[:2]
         assert cont1.sha1 != cont2.sha1
@@ -2981,6 +2991,8 @@
 
         actually_present = swh_storage.content_find({"sha1": content.sha1})
         assert actually_present[0] == content
+        assert actually_present[0].ctime is not None
+        assert actually_present[0].ctime.tzinfo is not None
 
     def test_content_find_with_present_content(self, swh_storage, sample_data):
         content = sample_data.content