diff --git a/substrate/frame/support/procedural/src/construct_runtime/mod.rs b/substrate/frame/support/procedural/src/construct_runtime/mod.rs
index 54ed15f7b1d36d6ee5eb724381152af03bef60c8..6e95fdf116a6fefe92e3fa94f91f4424013aa35f 100644
--- a/substrate/frame/support/procedural/src/construct_runtime/mod.rs
+++ b/substrate/frame/support/procedural/src/construct_runtime/mod.rs
@@ -233,25 +233,38 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream {
 	let input_copy = input.clone();
 	let definition = syn::parse_macro_input!(input as RuntimeDeclaration);
 
-	let res = match definition {
-		RuntimeDeclaration::Implicit(implicit_def) =>
-			check_pallet_number(input_copy.clone().into(), implicit_def.pallets.len()).and_then(
-				|_| construct_runtime_implicit_to_explicit(input_copy.into(), implicit_def),
-			),
-		RuntimeDeclaration::Explicit(explicit_decl) => check_pallet_number(
-			input_copy.clone().into(),
-			explicit_decl.pallets.len(),
-		)
-		.and_then(|_| {
-			construct_runtime_explicit_to_explicit_expanded(input_copy.into(), explicit_decl)
-		}),
-		RuntimeDeclaration::ExplicitExpanded(explicit_decl) =>
-			check_pallet_number(input_copy.into(), explicit_decl.pallets.len())
-				.and_then(|_| construct_runtime_final_expansion(explicit_decl)),
+	let (check_pallet_number_res, res) = match definition {
+		RuntimeDeclaration::Implicit(implicit_def) => (
+			check_pallet_number(input_copy.clone().into(), implicit_def.pallets.len()),
+			construct_runtime_implicit_to_explicit(input_copy.into(), implicit_def),
+		),
+		RuntimeDeclaration::Explicit(explicit_decl) => (
+			check_pallet_number(input_copy.clone().into(), explicit_decl.pallets.len()),
+			construct_runtime_explicit_to_explicit_expanded(input_copy.into(), explicit_decl),
+		),
+		RuntimeDeclaration::ExplicitExpanded(explicit_decl) => (
+			check_pallet_number(input_copy.into(), explicit_decl.pallets.len()),
+			construct_runtime_final_expansion(explicit_decl),
+		),
 	};
 
 	let res = res.unwrap_or_else(|e| e.to_compile_error());
 
+	// We want to provide better error messages to the user and thus, handle the error here
+	// separately. If there is an error, we print the error and still generate all of the code to
+	// get in overall less errors for the user.
+	let res = if let Err(error) = check_pallet_number_res {
+		let error = error.to_compile_error();
+
+		quote! {
+			#error
+
+			#res
+		}
+	} else {
+		res
+	};
+
 	let res = expander::Expander::new("construct_runtime")
 		.dry(std::env::var("EXPAND_MACROS").is_err())
 		.verbose(true)
diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.stderr b/substrate/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.stderr
index 3b6329c650fa65208e01c7d991e321f256b7eecf..6160f8234a350cc3ee0a0761cab0eed6ea022525 100644
--- a/substrate/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.stderr
+++ b/substrate/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.stderr
@@ -4,88 +4,24 @@ error: The number of pallets exceeds the maximum number of tuple elements. To in
 67 |     pub struct Runtime
    |     ^^^
 
-error[E0412]: cannot find type `RuntimeCall` in this scope
-  --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:35:64
-   |
-35 | pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<u32, RuntimeCall, Signature, ()>;
-   |                                                                ^^^^^^^^^^^ not found in this scope
-   |
-help: you might be missing a type parameter
-   |
-35 | pub type UncheckedExtrinsic<RuntimeCall> = generic::UncheckedExtrinsic<u32, RuntimeCall, Signature, ()>;
-   |                            +++++++++++++
-
-error[E0412]: cannot find type `Runtime` in this scope
-  --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:37:25
-   |
-37 | impl pallet::Config for Runtime {}
-   |                         ^^^^^^^ not found in this scope
-
-error[E0412]: cannot find type `Runtime` in this scope
-  --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:40:31
-   |
-40 | impl frame_system::Config for Runtime {
-   |                               ^^^^^^^ not found in this scope
-
-error[E0412]: cannot find type `RuntimeOrigin` in this scope
-  --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:42:23
-   |
-42 |     type RuntimeOrigin = RuntimeOrigin;
-   |                          ^^^^^^^^^^^^^
-   |
-help: you might have meant to use the associated type
-   |
-42 |     type RuntimeOrigin = Self::RuntimeOrigin;
-   |                          ++++++
-
-error[E0412]: cannot find type `RuntimeCall` in this scope
-  --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:44:21
-   |
-44 |     type RuntimeCall = RuntimeCall;
-   |                        ^^^^^^^^^^^
-   |
-help: you might have meant to use the associated type
-   |
-44 |     type RuntimeCall = Self::RuntimeCall;
-   |                        ++++++
-
-error[E0412]: cannot find type `RuntimeEvent` in this scope
-  --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:50:22
-   |
-50 |     type RuntimeEvent = RuntimeEvent;
-   |                         ^^^^^^^^^^^^
-   |
-help: you might have meant to use the associated type
-   |
-50 |     type RuntimeEvent = Self::RuntimeEvent;
-   |                         ++++++
-
-error[E0412]: cannot find type `PalletInfo` in this scope
-  --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:56:20
-   |
-56 |     type PalletInfo = PalletInfo;
-   |                       ^^^^^^^^^^
-   |
-help: you might have meant to use the associated type
-   |
-56 |     type PalletInfo = Self::PalletInfo;
-   |                       ++++++
-help: consider importing one of these items
-   |
-18 + use frame_benchmarking::__private::traits::PalletInfo;
-   |
-18 + use frame_support::traits::PalletInfo;
-   |
-
-error[E0412]: cannot find type `RuntimeTask` in this scope
-  --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:39:1
-   |
-39 | #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in the macro `frame_system::config_preludes::TestDefaultConfig` which comes from the expansion of the macro `frame_support::macro_magic::forward_tokens_verbatim` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: you might have meant to use the associated type
-  --> $WORKSPACE/substrate/frame/system/src/lib.rs
-   |
-   |             type Self::RuntimeTask = ();
-   |                  ++++++
+error: recursion limit reached while expanding `frame_support::__private::tt_return!`
+   --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:22:1
+    |
+22  | /  #[frame_support::pallet]
+23  | |  mod pallet {
+24  | |      #[pallet::config]
+25  | |      pub trait Config: frame_system::Config {}
+...   |
+66  | |/ construct_runtime! {
+67  | ||     pub struct Runtime
+68  | ||     {
+69  | ||         System: frame_system::{Pallet, Call, Storage, Config<T>, Event<T>},
+...   ||
+180 | ||     }
+181 | || }
+    | ||_^
+    |  |_|
+    |    in this macro invocation
+    |
+    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`$CRATE`)
+    = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)