diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index f3b8999883ab2d1892ee769fe66ca2b6409a4419..c45db3b1859d0a67d36ec9270d8ce69c7ed5ade7 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -576,6 +576,33 @@ std::string utf8str_truncate(const std::string& utf8str, const S32 max_len)
 	}
 }
 
+std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len)
+{
+    if (0 == symbol_len)
+    {
+        return std::string();
+    }
+    if ((S32)utf8str.length() <= symbol_len)
+    {
+        return utf8str;
+    }
+    else
+    {
+        int len = 0, byteIndex = 0;
+        const char* aStr = utf8str.c_str();
+        size_t origSize = utf8str.size();
+
+        for (byteIndex = 0; len < symbol_len && byteIndex < origSize; byteIndex++)
+        {
+            if ((aStr[byteIndex] & 0xc0) != 0x80)
+            {
+                len += 1;
+            }
+        }
+        return utf8str.substr(0, byteIndex);
+    }
+}
+
 std::string utf8str_substChar(
 	const std::string& utf8str,
 	const llwchar target_char,
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 393f6d7a8c1534ef0c796079c04f7136d8fb1bcd..a40db0f8cc786473daff03886aa1a19a78f8be27 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -563,6 +563,17 @@ LL_COMMON_API S32 utf8str_compare_insensitive(
 	const std::string& lhs,
 	const std::string& rhs);
 
+/**
+* @brief Properly truncate a utf8 string to a maximum character count.
+*
+* If symbol_len is longer than the string passed in, the return
+* value == utf8str.
+* @param utf8str A valid utf8 string to truncate.
+* @param symbol_len The maximum number of symbols in the return value.
+* @return Returns a valid utf8 string with symbol count <= max_len.
+*/
+LL_COMMON_API std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len);
+
 /**
  * @brief Replace all occurences of target_char with replace_char
  *
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index a08cf91a69dbcbb85c1ec4c3427699e597285ff3..492c9315d13bb3dd4bd292a173c3b4b720be389e 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -400,12 +400,7 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
 
 	if (mMaxLengthChars)
 	{
-		LLWString truncated_wstring = utf8str_to_wstring(truncated_utf8);
-		if (truncated_wstring.size() > (U32)mMaxLengthChars)
-		{
-			truncated_wstring = truncated_wstring.substr(0, mMaxLengthChars);
-		}
-		mText.assign(wstring_to_utf8str(truncated_wstring));
+		mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars));
 	}
 
 	if (all_selected)
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index ae8e78a9d688518ee52dcf132d372102683f4645..ded814bbebc1c39e87c20ea238c6cb6f7b5aefbb 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -67,7 +67,7 @@
     follows="left|top"
     height="32"
     left_pad="-11"
-    max_length_bytes="64"
+    max_length_chars="16"
     text_pad_left="8"
     name="password_edit"
     label="Password"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index dc6e27a1ee580acaba87074f5bc056d914112629..35b80c56abe7cc0f2837fa2905b1065e0d6699fa 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -124,7 +124,7 @@
             width="200"
             height="32"
             left="220"
-            max_length_bytes="64"
+            max_length_chars="16"
             name="password_edit"
             label="Password"
             text_pad_left="8"