diff --git a/django/db/models/query.py b/django/db/models/query.py
index 175073b961..9f2332a60e 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -23,7 +23,7 @@ from django.db import (
 from django.db.models import AutoField, DateField, DateTimeField, Field, sql
 from django.db.models.constants import LOOKUP_SEP, OnConflict
 from django.db.models.deletion import Collector
-from django.db.models.expressions import Case, F, Value, When
+from django.db.models.expressions import Case, DatabaseDefault, F, Value, When
 from django.db.models.functions import Cast, Trunc
 from django.db.models.query_utils import FilteredRelation, Q
 from django.db.models.sql.constants import GET_ITERATOR_CHUNK_SIZE, ROW_COUNT
@@ -789,7 +789,10 @@ class QuerySet(AltersData):
         objs = list(objs)
         self._prepare_for_bulk_create(objs)
         with transaction.atomic(using=self.db, savepoint=False):
-            objs_without_pk, objs_with_pk = partition(lambda o: o._is_pk_set(), objs)
+            objs_without_pk, objs_with_pk = partition(
+                lambda o: o._is_pk_set() and not isinstance(o.pk, DatabaseDefault),
+                objs,
+            )
             if objs_with_pk:
                 returned_columns = self._batched_insert(
                     objs_with_pk,
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index 91ce0bac69..e16d6668ee 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -2427,10 +2427,11 @@ This has a number of caveats though:
 * The model's ``save()`` method will not be called, and the ``pre_save`` and
   ``post_save`` signals will not be sent.
 * It does not work with child models in a multi-table inheritance scenario.
-* If the model's primary key is an :class:`~django.db.models.AutoField` and
-  ``ignore_conflicts`` is False, the primary key attribute can only be
-  retrieved on certain databases (currently PostgreSQL, MariaDB, and SQLite
-  3.35+). On other databases, it will not be set.
+* If the model's primary key is an :class:`~django.db.models.AutoField` or has
+  a :attr:`~django.db.models.Field.db_default` value, and ``ignore_conflicts``
+  is ``False``, the primary key attribute can only be retrieved on certain
+  databases (currently PostgreSQL, MariaDB, and SQLite 3.35+). On other
+  databases, it will not be set.
 * It does not work with many-to-many relationships.
 * It casts ``objs`` to a list, which fully evaluates ``objs`` if it's a
   generator. The cast allows inspecting all objects so that any objects with a
diff --git a/tests/bulk_create/models.py b/tests/bulk_create/models.py
index f0df9da66e..4b74b7ef56 100644
--- a/tests/bulk_create/models.py
+++ b/tests/bulk_create/models.py
@@ -147,3 +147,7 @@ class RelatedModel(models.Model):
 class DbDefaultModel(models.Model):
     name = models.CharField(max_length=10)
     created_at = models.DateTimeField(db_default=Now())
+
+
+class DbDefaultPrimaryKey(models.Model):
+    id = models.DateTimeField(primary_key=True, db_default=Now())
diff --git a/tests/bulk_create/tests.py b/tests/bulk_create/tests.py
index 83ff8e4514..9bcf92e4cf 100644
--- a/tests/bulk_create/tests.py
+++ b/tests/bulk_create/tests.py
@@ -1,3 +1,4 @@
+from datetime import datetime
 from math import ceil
 from operator import attrgetter
 
@@ -23,6 +24,7 @@ from .models import (
     BigAutoFieldModel,
     Country,
     DbDefaultModel,
+    DbDefaultPrimaryKey,
     FieldsWithDbColumns,
     NoFields,
     NullableFields,
@@ -866,3 +868,8 @@ class BulkCreateTests(TestCase):
             ctx[0]["sql"].count(created_at_quoted_name),
             2 if connection.features.can_return_rows_from_bulk_insert else 1,
         )
+
+    @skipUnlessDBFeature("can_return_rows_from_bulk_insert")
+    def test_db_default_primary_key(self):
+        (obj,) = DbDefaultPrimaryKey.objects.bulk_create([DbDefaultPrimaryKey()])
+        self.assertIsInstance(obj.id, datetime)