diff --git a/docs/components/radio-group.md b/docs/components/radio-group.md
index 49ad989b..dd930b7f 100644
--- a/docs/components/radio-group.md
+++ b/docs/components/radio-group.md
@@ -86,7 +86,60 @@ const App = () => (
 );
 ```
 
-### Custom Validity
+### Validation
+
+Setting the `required` attribute to make selecting a an option mandatory. If a value has not been selected, it will prevent the form from submitting and display an error message.
+
+```html preview
+<form class="validation">
+  <sl-radio-group label="Select an option" required>
+    <sl-radio name="a" value="1">Not me</sl-radio>
+    <sl-radio name="a" value="2">Me neither</sl-radio>
+    <sl-radio name="a" value="3">Choose me</sl-radio>
+  </sl-radio-group>
+  <br />
+  <sl-button type="submit" variant="primary">Submit</sl-button>
+</form>
+<script>
+  const form = document.querySelector('.validation');
+  // Handle form submit
+  form.addEventListener('submit', event => {
+    event.preventDefault();
+    alert('All fields are valid!');
+  });
+</script>
+```
+
+```jsx react
+import { SlButton, SlIcon, SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
+const App = () => {
+  function handleSubmit(event) {
+    event.preventDefault();
+    alert('All fields are valid!');
+  }
+  return (
+    <form class="custom-validity" onSubmit={handleSubmit} required>
+      <SlRadioGroup label="Select an option" onSlChange={handleChange}>
+        <SlRadio name="a" value="1">
+          Not me
+        </SlRadio>
+        <SlRadio name="a" value="2">
+          Me neither
+        </SlRadio>
+        <SlRadio name="a" value="3">
+          Choose me
+        </SlRadio>
+      </SlRadioGroup>
+      <br />
+      <SlButton type="submit" variant="primary">
+        Submit
+      </SlButton>
+    </form>
+  );
+};
+```
+
+#### Custom Validity
 
 Use the `setCustomValidity()` method to set a custom validation message. This will prevent the form from submitting and make the browser display the error message you provide. To clear the error, call this function with an empty string.
 
@@ -125,10 +178,10 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
 import { useEffect, useRef } from 'react';
 import { SlButton, SlIcon, SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
 const App = () => {
-  const radio = useRef(null);
+  const radioGroup = useRef(null);
   const errorMessage = 'You must choose this option';
-  function handleChange(event) {
-    radio.current.setCustomValidity(radio.current.checked ? '' : errorMessage);
+  function handleChange() {
+    radioGroup.current.setCustomValidity(radioGroup.current.value === '3' ? '' : errorMessage);
   }
   function handleSubmit(event) {
     event.preventDefault();
@@ -139,14 +192,14 @@ const App = () => {
   }, []);
   return (
     <form class="custom-validity" onSubmit={handleSubmit}>
-      <SlRadioGroup label="Select an option" value="1">
-        <SlRadio name="a" value="1" onSlChange={handleChange}>
+      <SlRadioGroup ref={radioGroup} label="Select an option" value="1" onSlChange={handleChange}>
+        <SlRadio name="a" value="1">
           Not me
         </SlRadio>
-        <SlRadio name="a" value="2" onSlChange={handleChange}>
+        <SlRadio name="a" value="2">
           Me neither
         </SlRadio>
-        <SlRadio ref={radio} name="a" value="3" onSlChange={handleChange}>
+        <SlRadio name="a" value="3">
           Choose me
         </SlRadio>
       </SlRadioGroup>
diff --git a/src/components/radio-group/radio-group.ts b/src/components/radio-group/radio-group.ts
index e4ab6818..a2e973f7 100644
--- a/src/components/radio-group/radio-group.ts
+++ b/src/components/radio-group/radio-group.ts
@@ -35,6 +35,7 @@ export default class SlRadioGroup extends LitElement {
   @state() private hasButtonGroup = false;
   @state() private isInvalid = false;
   @state() private errorMessage = '';
+  @state() private customErrorMessage = '';
 
   /** The radio group label. Required for proper accessibility. Alternatively, you can use the label slot. */
   @property() label = '';
@@ -64,7 +65,8 @@ export default class SlRadioGroup extends LitElement {
     this.preventInvalidSubmit();
   }
 
-  setCustomValidity(message: string) {
+  setCustomValidity(message = '') {
+    this.customErrorMessage = message;
     this.errorMessage = message;
 
     if (!message) {
@@ -77,11 +79,13 @@ export default class SlRadioGroup extends LitElement {
   }
 
   get validity(): ValidityState {
-    const isValid = (this.value && this.required) || !this.required;
-
+    const hasMissingData = !((this.value && this.required) || !this.required);
+    const hasCustomError = this.customErrorMessage !== '';
+    console.log(hasMissingData);
+    
     return {
       badInput: false,
-      customError: false,
+      customError: hasCustomError,
       patternMismatch: false,
       rangeOverflow: false,
       rangeUnderflow: false,
@@ -89,14 +93,16 @@ export default class SlRadioGroup extends LitElement {
       tooLong: false,
       tooShort: false,
       typeMismatch: false,
-      valid: isValid,
-      valueMissing: !isValid
+      valid: hasMissingData || hasCustomError ? false : true,
+      valueMissing: !hasMissingData
     };
   }
 
   reportValidity() {
     const validity = this.validity;
-    this.errorMessage = validity.valid ? '' : this.input.validationMessage;
+    console.log(validity);
+    
+    this.errorMessage = this.customErrorMessage || validity.valid ? '' : this.input.validationMessage;
     this.isInvalid = !validity.valid;
 
     if (!validity.valid) {
@@ -106,8 +112,9 @@ export default class SlRadioGroup extends LitElement {
 
   private preventInvalidSubmit() {
     this.closest('form')?.addEventListener('submit', e => {
+      this.reportValidity();
+
       if (this.isInvalid) {
-        this.showNativeErrorMessage();
         e.preventDefault();
         e.stopImmediatePropagation();
       }