diff --git a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx
index 66112b9c0b155e2022323a20b0e131b2a7f5bc16..82c67530aa227461b129c9dcdbe67c30e43aa555 100644
--- a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx
+++ b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx
@@ -138,10 +138,8 @@ export default function GuestRoleInfo({ guest }: GuestRoleInfoProps) {
                     render={({ field: { onChange, value } }) => (
                       <DatePicker
                         mask="____-__-__"
-                        disabled={roleInfo.start_date <= today}
                         label={t('input.roleStartDate')}
                         value={value}
-                        minDate={today}
                         maxDate={todayPlusMaxDays}
                         inputFormat="yyyy-MM-dd"
                         onChange={onChange}
@@ -159,8 +157,6 @@ export default function GuestRoleInfo({ guest }: GuestRoleInfoProps) {
                       <DatePicker
                         mask="____-__-__"
                         label={t('input.roleEndDate')}
-                        disabled={roleInfo.end_date < today}
-                        minDate={today}
                         maxDate={todayPlusMaxDays}
                         value={value}
                         inputFormat="yyyy-MM-dd"
diff --git a/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx b/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx
index f438dca6830fb68c0a7c7e9d5f803918a4d7ee66..bad293bdafaa1d6b4d809d4fc0dd3d46cd93e0a4 100644
--- a/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx
+++ b/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx
@@ -212,7 +212,6 @@ function NewGuestRole({ guest, reloadGuestInfo }: NewGuestRoleProps) {
                 label={t('input.roleStartDate')}
                 disabled={!roleTypeChoice}
                 value={field.value}
-                minDate={today}
                 maxDate={todayPlusMaxDays()}
                 inputFormat="yyyy-MM-dd"
                 onChange={(value) => {
@@ -232,7 +231,6 @@ function NewGuestRole({ guest, reloadGuestInfo }: NewGuestRoleProps) {
                 label={t('input.roleEndDate')}
                 disabled={!roleTypeChoice}
                 value={field.value}
-                minDate={today}
                 maxDate={todayPlusMaxDays()}
                 inputFormat="yyyy-MM-dd"
                 onChange={(value) => {
diff --git a/frontend/src/routes/sponsor/register/stepPersonForm.tsx b/frontend/src/routes/sponsor/register/stepPersonForm.tsx
index e796fa3361a2fffa1e6843e4237c7e84ea017bf0..1bccad5a56e43c6847053c8e47c097bfc0a5787a 100644
--- a/frontend/src/routes/sponsor/register/stepPersonForm.tsx
+++ b/frontend/src/routes/sponsor/register/stepPersonForm.tsx
@@ -19,6 +19,7 @@ import React, {
   useImperativeHandle,
   useState,
 } from 'react'
+import { addDays } from 'date-fns/fp'
 import { useTranslation } from 'react-i18next'
 import { RegisterFormData } from './formData'
 import { PersonFormMethods } from './personFormMethods'
@@ -44,9 +45,10 @@ const StepPersonForm = forwardRef(
     const [selectedRoleType, setSelectedRoleType] = useState(
       formData.role_type ? formData.role_type : ''
     )
+    const today = new Date()
+    const [todayPlusMaxDays, setTodayPlusMaxDays] = useState(today)
     const roleTypes = useRoleTypes()
     const { displayContactAtUnit, displayComment } = useContext(FeatureContext)
-    const today: Date = new Date()
 
     const roleTypeSort = () => (a: RoleTypeData, b: RoleTypeData) => {
       if (i18n.language === 'en') {
@@ -90,6 +92,14 @@ const StepPersonForm = forwardRef(
     const handleRoleTypeChange = (event: any) => {
       setValue('role_type', event.target.value)
       setSelectedRoleType(event.target.value)
+      const selectedRoleTypeInfo = roleTypes.find(
+        (rt) => rt.id === event.target.value
+      )
+      if (selectedRoleTypeInfo === undefined) {
+        setTodayPlusMaxDays(today)
+      } else {
+        setTodayPlusMaxDays(addDays(selectedRoleTypeInfo.max_days)(today))
+      }
     }
 
     function doSubmit() {
@@ -210,6 +220,7 @@ const StepPersonForm = forwardRef(
                   <DatePicker
                     mask="____-__-__"
                     label={t('input.roleStartDate')}
+                    maxDate={todayPlusMaxDays}
                     value={field.value}
                     inputFormat="yyyy-MM-dd"
                     onChange={(value) => {
@@ -232,6 +243,7 @@ const StepPersonForm = forwardRef(
                   <DatePicker
                     mask="____-__-__"
                     label={t('input.roleEndDate')}
+                    maxDate={todayPlusMaxDays}
                     value={field.value}
                     inputFormat="yyyy-MM-dd"
                     onChange={(value) => {
diff --git a/greg/signals.py b/greg/signals.py
index 5d427897b25e54fcd26edf53092444796c3c1331..de65ab3e8c62b15e960b358201c094eacdaccd04 100644
--- a/greg/signals.py
+++ b/greg/signals.py
@@ -134,9 +134,11 @@ def save_notification_callback(sender, instance, created, *args, **kwargs):
         return
     # Queue future notifications on start and end date for roles
     if isinstance(instance, Role) and hasattr(instance, "_changed_fields"):
+        today = datetime.date.today()
         if (
             "start_date" in instance._changed_fields  # pylint: disable=protected-access
             and instance.start_date
+            and instance.start_date != today
         ):
             Schedule.objects.create(
                 func="greg.signals._queue_role_start_notification",
@@ -144,7 +146,10 @@ def save_notification_callback(sender, instance, created, *args, **kwargs):
                 next_run=date_to_datetime_midnight(instance.start_date),
                 schedule_type=Schedule.ONCE,
             )
-        if "end_date" in instance._changed_fields:  # pylint: disable=protected-access
+        if (
+            "end_date" in instance._changed_fields  # pylint: disable=protected-access
+            and instance.end_date != today
+        ):
             Schedule.objects.create(
                 func="greg.signals._queue_role_end_notification",
                 args=f"{instance.id},True",
diff --git a/gregui/api/serializers/role.py b/gregui/api/serializers/role.py
index 0b867f092a1ca0f6eea1d9a1f71cbd9aa703a175..9afc3922f3e84db50b77c07679aad93ee6405b7b 100644
--- a/gregui/api/serializers/role.py
+++ b/gregui/api/serializers/role.py
@@ -28,29 +28,6 @@ class RoleSerializerUi(serializers.ModelSerializer):
             )
         ]
 
-    def validate_start_date(self, start_date):
-        """Enfore rules for start_date.
-
-        Must be present, can be blank, before today not allowed.
-        """
-        if not start_date:
-            return start_date
-        today = datetime.date.today()
-        # New start dates cannot be in the past
-        if start_date < today:
-            raise serializers.ValidationError("Start date cannot be in the past")
-
-        return start_date
-
-    def validate_end_date(self, end_date):
-        """Ensure rules for end_date are followed"""
-        today = datetime.date.today()
-        if end_date < today:
-            raise serializers.ValidationError("End date cannot be in the past")
-        if self.instance and self.instance.end_date < today:
-            raise serializers.ValidationError("Role has ended, cannot change end date")
-        return end_date
-
     def validate_orgunit(self, unit):
         """Enforce rules related to orgunit"""
         sponsor = self.context["sponsor"]
diff --git a/gregui/tests/api/serializers/test_role.py b/gregui/tests/api/serializers/test_role.py
index b36c2b7c4e152b7a82851a2612cd2806f0e276ba..604fa4cc68ff8871ed165174d8bab03eec82dc2c 100644
--- a/gregui/tests/api/serializers/test_role.py
+++ b/gregui/tests/api/serializers/test_role.py
@@ -25,8 +25,8 @@ def test_minimum_ok(role, sponsor_foo):
 
 
 @pytest.mark.django_db
-def test_start_date_past_fail(role, sponsor_foo):
-    """Should fail because of start_date in the past"""
+def test_start_date_past_ok(role, sponsor_foo):
+    """Should work even though start_date in the past"""
     ser = RoleSerializerUi(
         data={
             "person": role.person.id,
@@ -37,41 +37,29 @@ def test_start_date_past_fail(role, sponsor_foo):
         },
         context={"sponsor": sponsor_foo},
     )
-    with pytest.raises(
-        ValidationError,
-        match=re.escape(
-            "{'start_date': [ErrorDetail(string='Start date cannot be in the past', code='invalid')]}"
-        ),
-    ):
-        ser.is_valid(raise_exception=True)
+    assert ser.is_valid(raise_exception=True)
 
 
 @pytest.mark.django_db
-def test_end_date_past_fail(role, sponsor_foo):
-    """Should fail because of end_date in the past"""
+def test_end_date_past_ok(role, sponsor_foo):
+    """Should work even though end_date in the past"""
     ser = RoleSerializerUi(
         data={
             "person": role.person.id,
             "orgunit": role.orgunit.id,
             "type": role.type.id,
-            "start_date": datetime.date.today(),
+            "start_date": (timezone.now() - datetime.timedelta(days=12)).date(),
             "end_date": (timezone.now() - datetime.timedelta(days=10)).date(),
         },
         context={"sponsor": sponsor_foo},
     )
-    with pytest.raises(
-        ValidationError,
-        match=re.escape(
-            "{'end_date': [ErrorDetail(string='End date cannot be in the past', code='invalid')]}"
-        ),
-    ):
-        ser.is_valid(raise_exception=True)
+    assert ser.is_valid(raise_exception=True)
 
 
 @pytest.mark.django_db
-def test_end_date_expired_role_fail(role, sponsor_foo):
-    """New end date fail because role has ended"""
-    # Expire the role to ensure failure
+def test_end_date_expired_role_ok(role, sponsor_foo):
+    """Editing an expired role is allowed"""
+    # Expire the role
     role.end_date = datetime.date.today() - datetime.timedelta(days=10)
     role.save()
     # Try to change it
@@ -86,14 +74,7 @@ def test_end_date_expired_role_fail(role, sponsor_foo):
         },
         context={"sponsor": sponsor_foo},
     )
-    # Verify that a validation error is raised
-    with pytest.raises(
-        ValidationError,
-        match=re.escape(
-            "{'end_date': [ErrorDetail(string='Role has ended, cannot change end date', code='invalid')]}"
-        ),
-    ):
-        ser.is_valid(raise_exception=True)
+    assert ser.is_valid(raise_exception=True)
 
 
 @pytest.mark.django_db