diff --git a/README.md b/README.md
index 7319a14..2a99734 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,7 @@
 
 - [ ] 表字段协同注释
 - [ ] 操作审计日志
+- [ ] 文档导出功能
 
 ## 简介
 
diff --git a/api/src/main/java/com/databasir/api/ProjectController.java b/api/src/main/java/com/databasir/api/ProjectController.java
index f8fe747..c654e9e 100644
--- a/api/src/main/java/com/databasir/api/ProjectController.java
+++ b/api/src/main/java/com/databasir/api/ProjectController.java
@@ -1,5 +1,6 @@
 package com.databasir.api;
 
+import com.databasir.api.validator.CronExpressionValidator;
 import com.databasir.common.JsonData;
 import com.databasir.core.domain.project.data.*;
 import com.databasir.core.domain.project.service.ProjectService;
@@ -21,9 +22,12 @@ public class ProjectController {
 
     private final ProjectService projectService;
 
+    private final CronExpressionValidator cronExpressionValidator;
+
     @PostMapping(Routes.GroupProject.CREATE)
     @PreAuthorize("hasAnyAuthority('SYS_OWNER', 'GROUP_OWNER?groupId='+#request.groupId, 'GROUP_MEMBER?groupId='+#request.groupId)")
     public JsonData<Void> create(@RequestBody @Valid ProjectCreateRequest request) {
+        cronExpressionValidator.isValidCron(request);
         projectService.create(request);
         return JsonData.ok();
     }
@@ -32,6 +36,7 @@ public class ProjectController {
     @PreAuthorize("hasAnyAuthority('SYS_OWNER', 'GROUP_OWNER?groupId='+#groupId, 'GROUP_MEMBER?groupId='+#groupId)")
     public JsonData<Void> update(@RequestBody @Valid ProjectUpdateRequest request,
                                  @PathVariable Integer groupId) {
+        cronExpressionValidator.isValidCron(request);
         projectService.update(groupId, request);
         return JsonData.ok();
     }
diff --git a/api/src/main/java/com/databasir/api/validator/CronExpressionValidator.java b/api/src/main/java/com/databasir/api/validator/CronExpressionValidator.java
new file mode 100644
index 0000000..2742bcf
--- /dev/null
+++ b/api/src/main/java/com/databasir/api/validator/CronExpressionValidator.java
@@ -0,0 +1,33 @@
+package com.databasir.api.validator;
+
+import com.databasir.core.domain.DomainErrors;
+import com.databasir.core.domain.project.data.ProjectCreateRequest;
+import com.databasir.core.domain.project.data.ProjectUpdateRequest;
+import org.quartz.CronExpression;
+import org.springframework.stereotype.Component;
+
+import java.text.ParseException;
+
+@Component
+public class CronExpressionValidator {
+
+    public void isValidCron(ProjectUpdateRequest request) {
+        if (request.getProjectSyncRule().getIsAutoSync()) {
+            isValidCron(request.getProjectSyncRule().getAutoSyncCron());
+        }
+    }
+
+    public void isValidCron(ProjectCreateRequest request) {
+        if (request.getProjectSyncRule().getIsAutoSync()) {
+            isValidCron(request.getProjectSyncRule().getAutoSyncCron());
+        }
+    }
+
+    public void isValidCron(String cron) {
+        try {
+            new CronExpression(cron);
+        } catch (ParseException pe) {
+            throw DomainErrors.INVALID_CRON_EXPRESSION.exception("错误的 CRON 表达式:" + pe.getMessage(), pe);
+        }
+    }
+}
diff --git a/core/src/main/java/com/databasir/core/domain/DomainErrors.java b/core/src/main/java/com/databasir/core/domain/DomainErrors.java
index 25e70d0..40e6b61 100644
--- a/core/src/main/java/com/databasir/core/domain/DomainErrors.java
+++ b/core/src/main/java/com/databasir/core/domain/DomainErrors.java
@@ -22,7 +22,8 @@ public enum DomainErrors implements DatabasirErrors {
     PROJECT_NAME_DUPLICATE("A_10008", "项目名称已被占用"),
     CANNOT_UPDATE_SELF_ROLE("A_10009", "无法对自己执行角色变更的操作"),
     UPDATE_PASSWORD_CONFIRM_FAILED("A_10010", "两次密码输入不一致"),
-    ORIGIN_PASSWORD_NOT_CORRECT("A_10011", "原密码不正确");
+    ORIGIN_PASSWORD_NOT_CORRECT("A_10011", "原密码不正确"),
+    INVALID_CRON_EXPRESSION("A_10012", "不合法的 cron 表达式");
 
     private final String errCode;