diff --git a/meta/classes-global/insane.bbclass b/meta/classes-global/insane.bbclass
index 04700be71c..296cfba0fe 100644
--- a/meta/classes-global/insane.bbclass
+++ b/meta/classes-global/insane.bbclass
@@ -49,6 +49,9 @@ ERROR_QA ?= "\
 ERROR_QA:append = " ${@bb.utils.filter('DISTRO_FEATURES', 'usrmerge', d)}"
 WARN_QA:append:layer-core = " missing-metadata missing-maintainer"
 
+WARN_QA:append = " missing-srcrev"
+ERROR_QA:append:layer-core = " missing-srcrev"
+
 FAKEROOT_QA = "host-user-contaminated"
 FAKEROOT_QA[doc] = "QA tests which need to run under fakeroot. If any \
 enabled tests are listed here, the do_package_qa task will run under fakeroot."
@@ -1455,6 +1458,34 @@ python do_qa_unpack() {
 python do_recipe_qa() {
     import re
 
+    def test_missing_srcrev(pn, d):
+        import bb.fetch2
+        src_uri = (d.getVar('SRC_URI', False) or '').split()
+        for uri in src_uri:
+            try:
+                (scheme, _, _, _, _, params) = bb.fetch2.decodeurl(uri)
+            except Exception:
+                continue
+            if scheme not in ('git', 'gitsm', 'hg', 'svn'):
+                continue
+            if params.get('rev', ''):
+                continue
+            name = params.get('name', '') or 'default'
+            candidates = [
+                'SRCREV_%s:pn-%s' % (name, pn),
+                'SRCREV_%s' % name,
+                'SRCREV:pn-%s' % pn,
+                'SRCREV',
+            ]
+            raw = None
+            for candidate in candidates:
+                raw = d.getVar(candidate, False)
+                if raw:
+                    break
+            if not raw or raw == 'INVALID':
+                oe.qa.handle_error("missing-srcrev",
+                    "%s: %s not set for SCM URI %s" % (pn, candidates[-1], uri), d)
+
     def test_naming(pn, d):
         if pn.endswith("-native") and not bb.data.inherits_class("native", d):
             oe.qa.handle_error("recipe-naming", "Recipe %s appears native but is not, should inherit native" % pn, d)
@@ -1497,6 +1528,7 @@ python do_recipe_qa() {
 
     pn = d.getVar('PN')
     test_naming(pn, d)
+    test_missing_srcrev(pn, d)
     test_missing_metadata(pn, d)
     test_missing_maintainer(pn, d)
     test_srcuri(pn, d)
