diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl
index 08ce5172574ac..6101b28ab0cdd 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl
@@ -23,7 +23,7 @@ codegen_gcc_invalid_monomorphization_unsupported_element =
     invalid monomorphization of `{$name}` intrinsic: unsupported {$name} from `{$in_ty}` with element `{$elem_ty}` to `{$ret_ty}`
 
 codegen_gcc_invalid_monomorphization_invalid_bitmask =
-    invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
+    invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
 
 codegen_gcc_invalid_monomorphization_simd_shuffle =
     invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
index c8c7afb5f9196..4924105128db6 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
@@ -179,9 +179,9 @@ codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$
 
 codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
 
-codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error}
+codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
 
-codegen_ssa_read_file = failed to read file: {message}
+codegen_ssa_read_file = failed to read file: {$message}
 
 codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
 
diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs
index 32338f9dfc5e3..08098c9bb2a85 100644
--- a/compiler/rustc_macros/src/diagnostics/fluent.rs
+++ b/compiler/rustc_macros/src/diagnostics/fluent.rs
@@ -4,7 +4,10 @@ use annotate_snippets::{
 };
 use fluent_bundle::{FluentBundle, FluentError, FluentResource};
 use fluent_syntax::{
-    ast::{Attribute, Entry, Identifier, Message},
+    ast::{
+        Attribute, Entry, Expression, Identifier, InlineExpression, Message, Pattern,
+        PatternElement,
+    },
     parser::ParserError,
 };
 use proc_macro::{Diagnostic, Level, Span};
@@ -185,9 +188,12 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
         };
 
         let mut constants = TokenStream::new();
+        let mut messagerefs = Vec::new();
         for entry in resource.entries() {
             let span = res.krate.span();
-            if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
+            if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) =
+                entry
+            {
                 let _ = previous_defns.entry(name.to_string()).or_insert(path_span);
 
                 if name.contains('-') {
@@ -200,6 +206,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
                     .emit();
                 }
 
+                if let Some(Pattern { elements }) = value {
+                    for elt in elements {
+                        if let PatternElement::Placeable {
+                            expression:
+                                Expression::Inline(InlineExpression::MessageReference { id, .. }),
+                        } = elt
+                        {
+                            messagerefs.push((id.name, *name));
+                        }
+                    }
+                }
+
                 // Require that the message name starts with the crate name
                 // `hir_typeck_foo_bar` (in `hir_typeck.ftl`)
                 // `const_eval_baz` (in `const_eval.ftl`)
@@ -258,6 +276,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
             }
         }
 
+        for (mref, name) in messagerefs.into_iter() {
+            if !previous_defns.contains_key(mref) {
+                Diagnostic::spanned(
+                    path_span,
+                    Level::Error,
+                    format!("referenced message `{mref}` does not exist (in message `{name}`)"),
+                )
+                .help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)"))
+                .emit();
+            }
+        }
+
         if let Err(errs) = bundle.add_resource(resource) {
             for e in errs {
                 match e {
diff --git a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl
new file mode 100644
index 0000000000000..0cd8229b23010
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl
@@ -0,0 +1 @@
+missing_message_ref = {message}
diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs
index 4e8147e2b76dc..74303e97dba94 100644
--- a/tests/ui-fulldeps/fluent-messages/test.rs
+++ b/tests/ui-fulldeps/fluent-messages/test.rs
@@ -96,3 +96,12 @@ mod missing_crate_name {
 
     use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, test_crate_foo, with_hyphens};
 }
+
+mod missing_message_ref {
+    use super::fluent_messages;
+
+    fluent_messages! {
+        missing => "./missing-message-ref.ftl"
+//~^ ERROR referenced message `message` does not exist
+    }
+}
diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr
index d1cd4fe26da27..2631b0a623275 100644
--- a/tests/ui-fulldeps/fluent-messages/test.stderr
+++ b/tests/ui-fulldeps/fluent-messages/test.stderr
@@ -93,6 +93,14 @@ LL |         test_crate => "./missing-crate-name.ftl",
    |
    = help: replace any '-'s with '_'s
 
-error: aborting due to 10 previous errors
+error: referenced message `message` does not exist (in message `missing_message_ref`)
+  --> $DIR/test.rs:104:20
+   |
+LL |         missing => "./missing-message-ref.ftl"
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: you may have meant to use a variable reference (`{$message}`)
+
+error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0428`.