diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index e9274466dae1312bcf6b173c2984af67b8e08fc8..28752da46679bc4923de10136aed602e1e8d9dcf 100755
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -148,9 +148,12 @@ sub VALIDATORS {
         elsif ($field->type == FIELD_TYPE_DATETIME) {
             $validator = \&_check_datetime_field;
         }
-        else {
+        elsif ($field->type == FIELD_TYPE_FREETEXT) {
             $validator = \&_check_freetext_field;
         }
+        else {
+            $validator = \&_check_default_field;
+        }
         $validators->{$field->name} = $validator;
     }
 
@@ -1074,8 +1077,6 @@ sub _check_estimated_time {
     return $_[0]->_check_time($_[1], 'estimated_time');
 }
 
-sub _check_freetext_field { return defined $_[1] ? trim($_[1]) : ''; }
-
 sub _check_groups {
     my ($invocant, $product, $group_ids) = @_;
 
@@ -1373,6 +1374,18 @@ sub _check_datetime_field {
     return $date_time
 }
 
+sub _check_default_field { return defined $_[1] ? trim($_[1]) : ''; }
+
+sub _check_freetext_field {
+    my ($invocant, $text) = @_;
+
+    $text = (defined $text) ? trim($text) : '';
+    if (length($text) > MAX_FREETEXT_LENGTH) {
+        ThrowUserError('freetext_too_long', { text => $text });
+    }
+    return $text;
+}
+
 sub _check_multi_select_field {
     my ($invocant, $values, $field) = @_;
     return [] if !$values;
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 3c02c3902febafe1b8149445074e61559cb6d71f..ee064bb85b7d4aeaf0dba33f01e54a222249afef 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -149,6 +149,7 @@ use File::Basename;
     MAX_LEN_QUERY_NAME
     MAX_MILESTONE_SIZE
     MAX_COMPONENT_SIZE
+    MAX_FREETEXT_LENGTH
 );
 
 @Bugzilla::Constants::EXPORT_OK = qw(contenttypes);
@@ -423,6 +424,9 @@ use constant MAX_MILESTONE_SIZE => 20;
 # The longest component name allowed.
 use constant MAX_COMPONENT_SIZE => 64;
 
+# Maximum length allowed for free text fields.
+use constant MAX_FREETEXT_LENGTH => 255;
+
 sub bz_locations {
     # We know that Bugzilla/Constants.pm must be in %INC at this point.
     # So the only question is, what's the name of the directory
diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm
index 7148b78cb528b3b102ce74ccd2302dd30ddbb3cb..c4361e679415ee2ecd211a33f9888ed0bee35ac7 100755
--- a/Bugzilla/WebService/Bug.pm
+++ b/Bugzilla/WebService/Bug.pm
@@ -473,8 +473,8 @@ for more details.
 
 =item 104 (Invalid Field)
 
-One of the drop-down fields has an invalid value. The error message will
-have more detail.
+One of the drop-down fields has an invalid value, or a value entered in a
+text field is too long. The error message will have more detail.
 
 =item 105 (Invalid Component)
 
diff --git a/Bugzilla/WebService/Constants.pm b/Bugzilla/WebService/Constants.pm
index a1ecb53ed7b3c4213aa4f1a428064e9d78df421a..d641b6e7010d0be5c4400ce6c750a910d65deedd 100755
--- a/Bugzilla/WebService/Constants.pm
+++ b/Bugzilla/WebService/Constants.pm
@@ -65,6 +65,7 @@ use constant WS_ERROR_CODE => {
     alias_has_comma_or_space => 103,
     # Misc. bug field errors
     illegal_field => 104,
+    freetext_too_long => 104,
     # Component errors
     require_component       => 105,
     component_name_too_long => 105,
diff --git a/template/en/default/bug/field.html.tmpl b/template/en/default/bug/field.html.tmpl
index ea33d3ad0286fdb2a798b5e7b62b0bd2ba27d8d6..1ba0b1784a45bbb50fe64fd8a361bb24688fcb62 100644
--- a/template/en/default/bug/field.html.tmpl
+++ b/template/en/default/bug/field.html.tmpl
@@ -41,8 +41,9 @@
 [% IF editable %]
   [% SWITCH field.type %]
     [% CASE constants.FIELD_TYPE_FREETEXT %]
-        <input name="[% field.name FILTER html %]" 
-               value="[% value FILTER html %]" size="60">
+        <input id="[% field.name FILTER html %]" name="[% field.name FILTER html %]"
+               value="[% value FILTER html %]" size="60"
+               maxlength="[% constants.MAX_FREETEXT_LENGTH FILTER none %]">
     [% CASE constants.FIELD_TYPE_DATETIME %]
       <input name="[% field.name FILTER html %]" size="20"
              id="[% field.name FILTER html %]"
diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
index 46ed901a2af9ab0eed0a7fce09254e8dc8a15820..7bce4ad98a167c71e735cbc84ed7495f4f4ae930 100644
--- a/template/en/default/global/user-error.html.tmpl
+++ b/template/en/default/global/user-error.html.tmpl
@@ -592,6 +592,13 @@
     The sort key must be an integer between 0 and 32767 inclusive.
     It cannot be <em>[% sortkey FILTER html %]</em>.
 
+  [% ELSIF error == "freetext_too_long" %]
+    [% title = "Text Too Long" %]
+    The text you entered is too long ([% text.length FILTER html %] characters,
+    above the maximum length allowed of [% constants.MAX_FREETEXT_LENGTH FILTER none %]
+    characters):
+    <p><em>[% text FILTER html %]</em></p>
+
   [% ELSIF error == "group_cannot_delete" %]
     [% title = "Cannot Delete Group" %]
     The <em>[% name FILTER html %]</em> group cannot be deleted because