diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs
index eecc93e16666607a7f98b228bbd5fb885993b147..ca6e6b1822d45ad2e54415701b36ae3dd08739e1 100644
--- a/substrate/bin/node-template/runtime/src/lib.rs
+++ b/substrate/bin/node-template/runtime/src/lib.rs
@@ -222,6 +222,7 @@ impl pallet_grandpa::Config for Runtime {
 	type HandleEquivocation = ();
 
 	type WeightInfo = ();
+	type MaxAuthorities = MaxAuthorities;
 }
 
 parameter_types! {
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index 4cf313f8d26f099be3ba331a011f2d201a15b48e..75b80cccd8cb663b93ae0a3b925ffd6c22b91306 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -1035,6 +1035,7 @@ impl pallet_grandpa::Config for Runtime {
 	>;
 
 	type WeightInfo = ();
+	type MaxAuthorities = MaxAuthorities;
 }
 
 parameter_types! {
diff --git a/substrate/frame/grandpa/src/lib.rs b/substrate/frame/grandpa/src/lib.rs
index cd75deea770b4b131f13d325a122f75c58ccbb88..687207151f4f4a0754bf8f2df7fc97664709d50c 100644
--- a/substrate/frame/grandpa/src/lib.rs
+++ b/substrate/frame/grandpa/src/lib.rs
@@ -33,7 +33,7 @@ pub use sp_finality_grandpa as fg_primitives;
 
 use sp_std::prelude::*;
 
-use codec::{self as codec, Decode, Encode};
+use codec::{self as codec, Decode, Encode, MaxEncodedLen};
 pub use fg_primitives::{AuthorityId, AuthorityList, AuthorityWeight, VersionedAuthorityList};
 use fg_primitives::{
 	ConsensusLog, EquivocationProof, ScheduledChange, SetId, GRANDPA_AUTHORITIES_KEY,
@@ -41,9 +41,11 @@ use fg_primitives::{
 };
 use frame_support::{
 	dispatch::DispatchResultWithPostInfo,
+	pallet_prelude::Get,
 	storage,
 	traits::{KeyOwnerProofSystem, OneSessionHandler, StorageVersion},
 	weights::{Pays, Weight},
+	WeakBoundedVec,
 };
 use sp_runtime::{generic::DigestItem, traits::Zero, DispatchResult, KeyTypeId};
 use sp_session::{GetSessionNumber, GetValidatorCount};
@@ -81,6 +83,7 @@ pub mod pallet {
 	#[pallet::pallet]
 	#[pallet::generate_store(pub(super) trait Store)]
 	#[pallet::storage_version(STORAGE_VERSION)]
+	#[pallet::generate_storage_info]
 	pub struct Pallet<T>(_);
 
 	#[pallet::config]
@@ -119,6 +122,10 @@ pub mod pallet {
 
 		/// Weights for this pallet.
 		type WeightInfo: WeightInfo;
+
+		/// Max Authorities in use
+		#[pallet::constant]
+		type MaxAuthorities: Get<u32>;
 	}
 
 	#[pallet::hooks]
@@ -133,13 +140,13 @@ pub mod pallet {
 							median,
 							ScheduledChange {
 								delay: pending_change.delay,
-								next_authorities: pending_change.next_authorities.clone(),
+								next_authorities: pending_change.next_authorities.to_vec(),
 							},
 						))
 					} else {
 						Self::deposit_log(ConsensusLog::ScheduledChange(ScheduledChange {
 							delay: pending_change.delay,
-							next_authorities: pending_change.next_authorities.clone(),
+							next_authorities: pending_change.next_authorities.to_vec(),
 						}));
 					}
 				}
@@ -147,7 +154,9 @@ pub mod pallet {
 				// enact the change if we've reached the enacting block
 				if block_number == pending_change.scheduled_at + pending_change.delay {
 					Self::set_grandpa_authorities(&pending_change.next_authorities);
-					Self::deposit_event(Event::NewAuthorities(pending_change.next_authorities));
+					Self::deposit_event(Event::NewAuthorities(
+						pending_change.next_authorities.to_vec(),
+					));
 					<PendingChange<T>>::kill();
 				}
 			}
@@ -291,7 +300,8 @@ pub mod pallet {
 	/// Pending change: (signaled at, scheduled change).
 	#[pallet::storage]
 	#[pallet::getter(fn pending_change)]
-	pub(super) type PendingChange<T: Config> = StorageValue<_, StoredPendingChange<T::BlockNumber>>;
+	pub(super) type PendingChange<T: Config> =
+		StorageValue<_, StoredPendingChange<T::BlockNumber, T::MaxAuthorities>>;
 
 	/// next block number where we can force a change.
 	#[pallet::storage]
@@ -355,15 +365,25 @@ pub trait WeightInfo {
 	fn note_stalled() -> Weight;
 }
 
+/// Bounded version of `AuthorityList`, `Limit` being the bound
+pub type BoundedAuthorityList<Limit> = WeakBoundedVec<(AuthorityId, AuthorityWeight), Limit>;
+
 /// A stored pending change.
-#[derive(Encode, Decode, TypeInfo)]
-pub struct StoredPendingChange<N> {
+/// `Limit` is the bound for `next_authorities`
+#[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]
+#[codec(mel_bound(Limit: Get<u32>))]
+#[scale_info(skip_type_params(Limit))]
+pub struct StoredPendingChange<N, Limit>
+where
+	Limit: Get<u32>,
+	N: MaxEncodedLen,
+{
 	/// The block number this was scheduled at.
 	pub scheduled_at: N,
 	/// The delay in blocks until it will be applied.
 	pub delay: N,
-	/// The next authority set.
-	pub next_authorities: AuthorityList,
+	/// The next authority set, weakly bounded in size by `Limit`.
+	pub next_authorities: BoundedAuthorityList<Limit>,
 	/// If defined it means the change was forced and the given block number
 	/// indicates the median last finalized block when the change was signaled.
 	pub forced: Option<N>,
@@ -372,7 +392,7 @@ pub struct StoredPendingChange<N> {
 /// Current state of the GRANDPA authority set. State transitions must happen in
 /// the same order of states defined below, e.g. `Paused` implies a prior
 /// `PendingPause`.
-#[derive(Decode, Encode, TypeInfo)]
+#[derive(Decode, Encode, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(test, derive(Debug, PartialEq))]
 pub enum StoredState<N> {
 	/// The current authority set is live, and GRANDPA is enabled.
@@ -465,6 +485,14 @@ impl<T: Config> Pallet<T> {
 				<NextForced<T>>::put(scheduled_at + in_blocks * 2u32.into());
 			}
 
+			let next_authorities = WeakBoundedVec::<_, T::MaxAuthorities>::force_from(
+				next_authorities,
+				Some(
+					"Warning: The number of authorities given is too big. \
+					A runtime configuration adjustment may be needed.",
+				),
+			);
+
 			<PendingChange<T>>::put(StoredPendingChange {
 				delay: in_blocks,
 				scheduled_at,
diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs
index 2f1b2630b224173364a5778392b474cae1175444..4e5e44ce36e7ac3b0c3463da8fcb458df973abd9 100644
--- a/substrate/frame/grandpa/src/mock.rs
+++ b/substrate/frame/grandpa/src/mock.rs
@@ -230,6 +230,7 @@ impl pallet_offences::Config for Test {
 parameter_types! {
 	pub const ReportLongevity: u64 =
 		BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * Period::get();
+	pub const MaxAuthorities: u32 = 100;
 }
 
 impl Config for Test {
@@ -250,6 +251,7 @@ impl Config for Test {
 		super::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
 
 	type WeightInfo = ();
+	type MaxAuthorities = MaxAuthorities;
 }
 
 pub fn grandpa_log(log: ConsensusLog<u64>) -> DigestItem<H256> {