diff --git a/builddefs/build_json.mk b/builddefs/build_json.mk
index 0c034eb2ae..e29d678e48 100644
--- a/builddefs/build_json.mk
+++ b/builddefs/build_json.mk
@@ -1,17 +1,17 @@
 # Look for a json keymap file
 ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.json)","")
     KEYMAP_JSON := $(MAIN_KEYMAP_PATH_5)/keymap.json
-    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
+    KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_5)
 else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.json)","")
     KEYMAP_JSON := $(MAIN_KEYMAP_PATH_4)/keymap.json
-    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
+    KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_4)
 else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.json)","")
     KEYMAP_JSON := $(MAIN_KEYMAP_PATH_3)/keymap.json
-    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
+    KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_3)
 else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.json)","")
     KEYMAP_JSON := $(MAIN_KEYMAP_PATH_2)/keymap.json
-    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
+    KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_2)
 else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.json)","")
     KEYMAP_JSON := $(MAIN_KEYMAP_PATH_1)/keymap.json
-    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
+    KEYMAP_JSON_PATH := $(MAIN_KEYMAP_PATH_1)
 endif
diff --git a/builddefs/build_keyboard.mk b/builddefs/build_keyboard.mk
index e93ab97cc1..b81e00b0d3 100644
--- a/builddefs/build_keyboard.mk
+++ b/builddefs/build_keyboard.mk
@@ -127,39 +127,44 @@ include $(INFO_RULES_MK)
 include $(BUILDDEFS_PATH)/build_json.mk
 
 # Pull in keymap level rules.mk
-ifeq ("$(wildcard $(KEYMAP_PATH))", "")
-    # Look through the possible keymap folders until we find a matching keymap.c
-    ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.c)","")
-        -include $(MAIN_KEYMAP_PATH_1)/rules.mk
-        KEYMAP_C := $(MAIN_KEYMAP_PATH_1)/keymap.c
-        KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
-    else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.c)","")
-        -include $(MAIN_KEYMAP_PATH_2)/rules.mk
-        KEYMAP_C := $(MAIN_KEYMAP_PATH_2)/keymap.c
-        KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
-    else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.c)","")
-        -include $(MAIN_KEYMAP_PATH_3)/rules.mk
-        KEYMAP_C := $(MAIN_KEYMAP_PATH_3)/keymap.c
-        KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
-    else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.c)","")
-        -include $(MAIN_KEYMAP_PATH_4)/rules.mk
-        KEYMAP_C := $(MAIN_KEYMAP_PATH_4)/keymap.c
-        KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
-    else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.c)","")
-        -include $(MAIN_KEYMAP_PATH_5)/rules.mk
-        KEYMAP_C := $(MAIN_KEYMAP_PATH_5)/keymap.c
-        KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
-    else ifneq ($(LAYOUTS),)
-        # If we haven't found a keymap yet fall back to community layouts
-        include $(BUILDDEFS_PATH)/build_layout.mk
-    else
-        $(call CATASTROPHIC_ERROR,Invalid keymap,Could not find keymap)
-        # this state should never be reached
-    endif
+# Look through the possible keymap folders until we find a matching keymap.c
+ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.c)","")
+    -include $(MAIN_KEYMAP_PATH_1)/rules.mk
+    KEYMAP_C := $(MAIN_KEYMAP_PATH_1)/keymap.c
+    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
+else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.c)","")
+    -include $(MAIN_KEYMAP_PATH_2)/rules.mk
+    KEYMAP_C := $(MAIN_KEYMAP_PATH_2)/keymap.c
+    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
+else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.c)","")
+    -include $(MAIN_KEYMAP_PATH_3)/rules.mk
+    KEYMAP_C := $(MAIN_KEYMAP_PATH_3)/keymap.c
+    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
+else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.c)","")
+    -include $(MAIN_KEYMAP_PATH_4)/rules.mk
+    KEYMAP_C := $(MAIN_KEYMAP_PATH_4)/keymap.c
+    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
+else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.c)","")
+    -include $(MAIN_KEYMAP_PATH_5)/rules.mk
+    KEYMAP_C := $(MAIN_KEYMAP_PATH_5)/keymap.c
+    KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
+else ifneq ($(LAYOUTS),)
+    # If we haven't found a keymap yet fall back to community layouts
+    include $(BUILDDEFS_PATH)/build_layout.mk
+# Not finding keymap.c is fine if we found a keymap.json
+else ifeq ("$(wildcard $(KEYMAP_JSON_PATH))", "")
+    $(call CATASTROPHIC_ERROR,Invalid keymap,Could not find keymap)
+    # this state should never be reached
 endif
 
 # Have we found a keymap.json?
 ifneq ("$(wildcard $(KEYMAP_JSON))", "")
+    ifneq ("$(wildcard $(KEYMAP_C))", "")
+        $(call WARNING_MESSAGE,Keymap is specified as both keymap.json and keymap.c -- keymap.json file wins.)
+    endif
+
+    KEYMAP_PATH := $(KEYMAP_JSON_PATH)
+
     KEYMAP_C := $(INTERMEDIATE_OUTPUT)/src/keymap.c
     KEYMAP_H := $(INTERMEDIATE_OUTPUT)/src/config.h
 
diff --git a/builddefs/message.mk b/builddefs/message.mk
index c7cc5171e7..7c8f87f990 100644
--- a/builddefs/message.mk
+++ b/builddefs/message.mk
@@ -103,6 +103,10 @@ MSG_BOOTLOADER_NOT_FOUND = $(ERROR_COLOR)ERROR:$(NO_COLOR) $(MSG_BOOTLOADER_NOT_
 BOOTLOADER_RETRY_TIME ?= 0.5
 MSG_BOOTLOADER_NOT_FOUND_QUICK_RETRY = $(MSG_BOOTLOADER_NOT_FOUND_BASE) Trying again every $(BOOTLOADER_RETRY_TIME)s (Ctrl+C to cancel)
 
+define WARNING_MESSAGE
+    $(shell printf "\n %-99s $(WARN_STRING)\n" "$1" >&2)
+endef
+
 define CATASTROPHIC_ERROR
     $(shell printf "\n * %-99s $(ERROR_STRING)\n" "$2" >&2)
     $(error $1)