diff --git a/grudge/op.py b/grudge/op.py
index 33a8f0161c16c017c0eabb8d879a95663afe6ad8..3cebfce9ca389b23e90a5fb44839360d5feba8cb 100644
--- a/grudge/op.py
+++ b/grudge/op.py
@@ -1046,15 +1046,15 @@ def _norm(dcoll: DiscretizationCollection, vec, p, dd):
     if isinstance(vec, Number):
         return np.fabs(vec)
     if p == 2:
-        return np.sqrt(
+        return np.real_if_close(np.sqrt(
             nodal_sum(
                 dcoll,
                 dd,
-                vec * _apply_mass_operator(dcoll, dd, dd, vec)
+                vec.conj() * _apply_mass_operator(dcoll, dd, dd, vec)
             )
-        )
+        ))
     elif p == np.inf:
-        return nodal_max(dcoll, dd, dcoll._setup_actx.np.fabs(vec))
+        return nodal_max(dcoll, dd, abs(vec))
     else:
         raise NotImplementedError("Unsupported value of p")
 
diff --git a/test/test_grudge.py b/test/test_grudge.py
index 83b084b4e9ee90a2e69ff79e392e9a979d22346b..2615b84870fd0c92cf3c068bb0241669e32f795b 100644
--- a/test/test_grudge.py
+++ b/test/test_grudge.py
@@ -1001,6 +1001,28 @@ def test_bessel(actx_factory):
 # }}}
 
 
+@pytest.mark.parametrize("p", [2, np.inf])
+def test_norm_complex(actx_factory, p):
+    actx = actx_factory()
+
+    dim = 2
+    mesh = mgen.generate_regular_rect_mesh(
+            a=(0,)*dim, b=(1,)*dim,
+            nelements_per_axis=(8,)*dim, order=1)
+    dcoll = DiscretizationCollection(actx, mesh, order=4)
+
+    nodes = thaw(dcoll.nodes(), actx)
+    f = nodes[0] + 1j * nodes[0]
+
+    norm = op.norm(dcoll, f, p)
+    if p == 2:
+        ref_norm = ((1/3)*dim)**0.5
+    elif p == np.inf:
+        ref_norm = 2**0.5
+
+    assert abs(norm-ref_norm) / abs(ref_norm) < 1e-13
+
+
 @pytest.mark.parametrize("p", [2, np.inf])
 def test_norm_obj_array(actx_factory, p):
     """Test :func:`grudge.op.norm` for object arrays."""