diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go
index 63049284d0..58c34473aa 100644
--- a/services/forms/repo_form.go
+++ b/services/forms/repo_form.go
@@ -27,7 +27,7 @@ import (
 // CreateRepoForm form for creating repository
 type CreateRepoForm struct {
 	UID           int64  `binding:"Required"`
-	RepoName      string `binding:"Required;AlphaDashDot;MaxSize(100)"`
+	RepoName      string `binding:"Required;AlphaDashDot;MaxSize(100)" preprocess:"TrimSpace"`
 	Private       bool
 	Description   string `binding:"MaxSize(2048)"`
 	DefaultBranch string `binding:"GitRefName;MaxSize(100)"`
diff --git a/tests/integration/repo_generate_test.go b/tests/integration/repo_generate_test.go
index c475c92eef..0b2870ad56 100644
--- a/tests/integration/repo_generate_test.go
+++ b/tests/integration/repo_generate_test.go
@@ -11,9 +11,11 @@ import (
 	"strings"
 	"testing"
 
+	repo_model "code.gitea.io/gitea/models/repo"
 	"code.gitea.io/gitea/models/unittest"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/modules/test"
 	"code.gitea.io/gitea/modules/translation"
 	"code.gitea.io/gitea/tests"
 
@@ -135,3 +137,19 @@ func TestRepoGenerateToOrg(t *testing.T) {
 
 	testRepoGenerate(t, session, "44", "user27", "template1", user, org, "generated2")
 }
+
+func TestRepoCreateFormTrimSpace(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+	session := loginUser(t, user.Name)
+
+	req := NewRequestWithValues(t, "POST", "/repo/create", map[string]string{
+		"_csrf":     GetCSRF(t, session, "/repo/create"),
+		"uid":       "2",
+		"repo_name": " spaced-name ",
+	})
+	resp := session.MakeRequest(t, req, http.StatusSeeOther)
+
+	assert.EqualValues(t, "/user2/spaced-name", test.RedirectURL(resp))
+	unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: 2, Name: "spaced-name"})
+}