diff --git a/integrations/privateactivity_test.go b/integrations/privateactivity_test.go
index e9beb7c116..bfdc2ef53e 100644
--- a/integrations/privateactivity_test.go
+++ b/integrations/privateactivity_test.go
@@ -45,7 +45,7 @@ func testPrivateActivityHelperEnablePrivateActivity(t *testing.T) {
 		"_csrf":                 GetCSRF(t, session, "/user/settings"),
 		"name":                  privateActivityTestUser,
 		"email":                 privateActivityTestUser + "@example.com",
-		"language":              "en-us",
+		"language":              "en-US",
 		"keep_activity_private": "1",
 	})
 	session.MakeRequest(t, req, http.StatusFound)
diff --git a/integrations/user_test.go b/integrations/user_test.go
index 999a182bfd..199d5e242f 100644
--- a/integrations/user_test.go
+++ b/integrations/user_test.go
@@ -30,7 +30,7 @@ func TestRenameUsername(t *testing.T) {
 		"_csrf":    GetCSRF(t, session, "/user/settings"),
 		"name":     "newUsername",
 		"email":    "user2@example.com",
-		"language": "en-us",
+		"language": "en-US",
 	})
 	session.MakeRequest(t, req, http.StatusFound)
 
@@ -100,7 +100,7 @@ func TestRenameReservedUsername(t *testing.T) {
 			"_csrf":    GetCSRF(t, session, "/user/settings"),
 			"name":     reservedUsername,
 			"email":    "user2@example.com",
-			"language": "en-us",
+			"language": "en-US",
 		})
 		resp := session.MakeRequest(t, req, http.StatusFound)
 
diff --git a/integrations/xss_test.go b/integrations/xss_test.go
index 425165dccc..2d83e1e106 100644
--- a/integrations/xss_test.go
+++ b/integrations/xss_test.go
@@ -24,7 +24,7 @@ func TestXSSUserFullName(t *testing.T) {
 		"name":      user.Name,
 		"full_name": fullName,
 		"email":     user.Email,
-		"language":  "en-us",
+		"language":  "en-US",
 	})
 	session.MakeRequest(t, req, http.StatusFound)
 
diff --git a/modules/auth/user_form.go b/modules/auth/user_form.go
index 32fde1570e..c0aafec9e4 100644
--- a/modules/auth/user_form.go
+++ b/modules/auth/user_form.go
@@ -202,7 +202,7 @@ type UpdateProfileForm struct {
 	KeepEmailPrivate    bool
 	Website             string `binding:"ValidUrl;MaxSize(255)"`
 	Location            string `binding:"MaxSize(50)"`
-	Language            string `binding:"Size(5)"`
+	Language            string
 	Description         string `binding:"MaxSize(255)"`
 	KeepActivityPrivate bool
 }
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 1500bf73e9..ff54bcd3b3 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -440,6 +440,7 @@ website = Website
 location = Location
 update_theme = Update Theme
 update_profile = Update Profile
+update_language_not_found = Language '%s' is not available.
 update_profile_success = Your profile has been updated.
 change_username = Your username has been changed.
 change_username_prompt = Note: username changes also change your account URL.
diff --git a/routers/user/setting/profile.go b/routers/user/setting/profile.go
index 6653230a39..74cc96cb85 100644
--- a/routers/user/setting/profile.go
+++ b/routers/user/setting/profile.go
@@ -19,6 +19,7 @@ import (
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/modules/util"
 
 	"github.com/unknwon/i18n"
 )
@@ -94,7 +95,14 @@ func ProfilePost(ctx *context.Context, form auth.UpdateProfileForm) {
 	ctx.User.KeepEmailPrivate = form.KeepEmailPrivate
 	ctx.User.Website = form.Website
 	ctx.User.Location = form.Location
-	ctx.User.Language = form.Language
+	if len(form.Language) != 0 {
+		if !util.IsStringInSlice(form.Language, setting.Langs) {
+			ctx.Flash.Error(ctx.Tr("settings.update_language_not_found", form.Language))
+			ctx.Redirect(setting.AppSubURL + "/user/settings")
+			return
+		}
+		ctx.User.Language = form.Language
+	}
 	ctx.User.Description = form.Description
 	ctx.User.KeepActivityPrivate = form.KeepActivityPrivate
 	if err := models.UpdateUserSetting(ctx.User); err != nil {