diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index d62a47547d20d48984bfa9bb7750d43e2d6f052f..bf54055a241da5e708caaa4415ca91377c6b73f2 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -211,6 +211,10 @@ def _read_spec_from_yaml(self, hash_key, installs, parent_key=None):
             child = self._read_spec_from_yaml(dep_hash, installs, hash_key)
             spec._add_dependency(child)
 
+        # Specs from the database need to be marked concrete because
+        # they represent actual installations.
+        spec._mark_concrete()
+
         return spec
 
 
diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py
index a434dad5c49d03e157474fb6feef7cd086c12744..d91fbe9f4e9544db7bca0ba3908461bb1325825e 100644
--- a/lib/spack/spack/directory_layout.py
+++ b/lib/spack/spack/directory_layout.py
@@ -212,9 +212,7 @@ def read_spec(self, path):
             spec = Spec.from_yaml(f)
 
         # Specs read from actual installations are always concrete
-        for s in spec.traverse():
-            s._normal = True
-            s._concrete = True
+        spec._mark_concrete()
 
         return spec
 
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index fb5ea5d02b4224c7c78e81292c3f2713f177d7f7..037ec97a5e8ae7910358276e29dd3cddacc4be12 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -833,7 +833,18 @@ def concretize(self):
             changed = any(changes)
             force=True
 
-        self._concrete = True
+        self._mark_concrete()
+
+
+    def _mark_concrete(self):
+        """Mark this spec and its dependencies as concrete.
+
+        Only for internal use -- client code should use "concretize"
+        unless there is a need to force a spec to be concrete.
+        """
+        for s in self.traverse():
+            s._normal = True
+            s._concrete = True
 
 
     def concretized(self):