diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 6e41e133502..637ebc5a717 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -36,6 +36,7 @@
   #endif
 #endif // ENABLE_AUTO_BED_LEVELING
 
+#define HAS_LCD_BUZZ (defined(ULTRALCD) || (defined(BEEPER) && BEEPER >= 0) || defined(LCD_USE_I2C_BUZZER))
 #define SERVO_LEVELING (defined(ENABLE_AUTO_BED_LEVELING) && PROBE_SERVO_DEACTIVATION_DELAY > 0)
 
 #ifdef MESH_BED_LEVELING
@@ -4091,7 +4092,7 @@ inline void gcode_M226() {
 
 #endif // NUM_SERVOS > 0
 
-#if BEEPER > 0 || defined(ULTRALCD) || defined(LCD_USE_I2C_BUZZER)
+#if HAS_LCD_BUZZ
 
   /**
    * M300: Play beep sound S<frequency Hz> P<duration ms>
@@ -4103,7 +4104,7 @@ inline void gcode_M226() {
     lcd_buzz(beepP, beepS);
   }
 
-#endif // BEEPER>0 || ULTRALCD || LCD_USE_I2C_BUZZER
+#endif // HAS_LCD_BUZZ
 
 #ifdef PIDTEMP
 
@@ -4507,27 +4508,50 @@ inline void gcode_M410() { quickStop(); }
 
 /**
  * M428: Set home_offset based on the distance between the
- *       current_position and the nearest "reference position."
- *       If an axis is past center the endstop position
+ *       current_position and the nearest "reference point."
+ *       If an axis is past center its endstop position
  *       is the reference-point. Otherwise it uses 0. This allows
  *       the Z offset to be set near the bed when using a max endstop.
  *
+ *       M428 can't be used more than 2cm away from 0 or an endstop.
+ *
  *       Use M206 to set these values directly.
  */
 inline void gcode_M428() {
+  bool err = false;
+  float new_offs[3], new_pos[3];
+  memcpy(new_pos, current_position, sizeof(new_pos));
+  memcpy(new_offs, home_offset, sizeof(new_offs));
   for (int8_t i = X_AXIS; i <= Z_AXIS; i++) {
-    float base = (current_position[i] > (min_pos[i] + max_pos[i]) / 2) ? base_home_pos(i) : 0,
-          diff = current_position[i] - base;
-    if (diff > -20 && diff < 20) {
-      home_offset[i] -= diff;
-      current_position[i] = base;
-    }
-    else {
-      SERIAL_ERROR_START;
-      SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR);
+    if (axis_known_position[i]) {
+      float base = (new_pos[i] > (min_pos[i] + max_pos[i]) / 2) ? base_home_pos(i) : 0,
+            diff = new_pos[i] - base;
+      if (diff > -20 && diff < 20) {
+        new_offs[i] -= diff;
+        new_pos[i] = base;
+      }
+      else {
+        SERIAL_ERROR_START;
+        SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR);
+        LCD_ALERTMESSAGEPGM("Err: Too far!");
+        #if HAS_LCD_BUZZ
+          enqueuecommands_P(PSTR("M300 S40 P200"));
+        #endif
+        err = true;
+        break;
+      }
     }
   }
-  sync_plan_position();
+
+  if (!err) {
+    memcpy(current_position, new_pos, sizeof(new_pos));
+    memcpy(home_offset, new_offs, sizeof(new_offs));
+    sync_plan_position();
+    LCD_ALERTMESSAGEPGM("Offset applied.");
+    #if HAS_LCD_BUZZ
+      enqueuecommands_P(PSTR("M300 S659 P200\nM300 S698 P200"));
+    #endif
+  }
 }
 
 /**
@@ -5277,11 +5301,11 @@ void process_commands() {
           break;
       #endif // NUM_SERVOS > 0
 
-      #if BEEPER > 0 || defined(ULTRALCD) || defined(LCD_USE_I2C_BUZZER)
+      #if HAS_LCD_BUZZ
         case 300: // M300 - Play beep tone
           gcode_M300();
           break;
-      #endif // BEEPER > 0 || ULTRALCD || LCD_USE_I2C_BUZZER
+      #endif // HAS_LCD_BUZZ
 
       #ifdef PIDTEMP
         case 301: // M301
diff --git a/Marlin/configurator/config/language.h b/Marlin/configurator/config/language.h
index d8ceafb1a56..a56ee522f81 100644
--- a/Marlin/configurator/config/language.h
+++ b/Marlin/configurator/config/language.h
@@ -161,6 +161,7 @@
 #define MSG_ERR_MATERIAL_INDEX              "M145 S<index> out of range (0-1)"
 #define MSG_ERR_M421_REQUIRES_XYZ           "M421 requires XYZ parameters"
 #define MSG_ERR_MESH_INDEX_OOB              "Mesh XY index is out of bounds"
+#define MSG_ERR_M428_TOO_FAR                "Too far from reference point"
 #define MSG_M119_REPORT                     "Reporting endstop status"
 #define MSG_ENDSTOP_HIT                     "TRIGGERED"
 #define MSG_ENDSTOP_OPEN                    "open"
diff --git a/Marlin/language.h b/Marlin/language.h
index 31239658eb7..02cd675c8bb 100644
--- a/Marlin/language.h
+++ b/Marlin/language.h
@@ -162,7 +162,7 @@
 #define MSG_ERR_MATERIAL_INDEX              "M145 S<index> out of range (0-1)"
 #define MSG_ERR_M421_REQUIRES_XYZ           "M421 requires XYZ parameters"
 #define MSG_ERR_MESH_INDEX_OOB              "Mesh XY index is out of bounds"
-#define MSG_ERR_M428_TOO_FAR                "Too far from home or origin position"
+#define MSG_ERR_M428_TOO_FAR                "Too far from reference point"
 #define MSG_M119_REPORT                     "Reporting endstop status"
 #define MSG_ENDSTOP_HIT                     "TRIGGERED"
 #define MSG_ENDSTOP_OPEN                    "open"
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 57e51136178..5ca09433767 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -442,8 +442,8 @@ static void lcd_main_menu() {
  * Set the home offset based on the current_position
  */
 void lcd_set_home_offsets() {
-  // Command with Audio feedback
-  enqueuecommands_P(PSTR("M428\nM300 S659 P200\nM300 S698 P200"));
+  // M428 Command
+  enqueuecommands_P(PSTR("M428"));
   lcd_return_to_status();
 }
 
@@ -1285,7 +1285,7 @@ void lcd_quick_feedback() {
       #define LCD_FEEDBACK_FREQUENCY_DURATION_MS (1000/6)
     #endif    
     lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
-  #elif defined(BEEPER) && BEEPER > -1
+  #elif defined(BEEPER) && BEEPER >= 0
     #ifndef LCD_FEEDBACK_FREQUENCY_HZ
       #define LCD_FEEDBACK_FREQUENCY_HZ 5000
     #endif
@@ -1718,12 +1718,12 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; }
 
   void lcd_buzz(long duration, uint16_t freq) {
     if (freq > 0) {
-      #if BEEPER > 0
+      #ifdef LCD_USE_I2C_BUZZER
+        lcd.buzz(duration, freq);
+      #elif defined(BEEPER) && BEEPER >= 0
         SET_OUTPUT(BEEPER);
         tone(BEEPER, freq, duration);
         delay(duration);
-      #elif defined(LCD_USE_I2C_BUZZER)
-        lcd.buzz(duration, freq);
       #else
         delay(duration);
       #endif
diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h
index 8f96f008ba6..956b7282861 100644
--- a/Marlin/ultralcd.h
+++ b/Marlin/ultralcd.h
@@ -106,7 +106,7 @@
   FORCE_INLINE void lcd_setstatuspgm(const char* message, const uint8_t level=0) {}
   FORCE_INLINE void lcd_buttons_update() {}
   FORCE_INLINE void lcd_reset_alert_level() {}
-  FORCE_INLINE void lcd_buzz(long duration,uint16_t freq) {}
+  FORCE_INLINE void lcd_buzz(long duration, uint16_t freq) {}
   FORCE_INLINE bool lcd_detected(void) { return true; }
 
   #define LCD_MESSAGEPGM(x) do{}while(0)