diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index e0a2f1e8619299de4cb6198d749d4f33613d0451..cdb2606ddc47106c1a0f49765e2ac1aa70593db0 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -375,12 +375,19 @@ class DynamicFormEntry extends VerySimpleModel {
         return $this->_fields;
     }
 
-    function isValid() {
+    /**
+     * Validate the form and indicate if there no errors.
+     *
+     * Parameters:
+     * $filter - (callback) function to receive each field and return
+     *      boolean true if the field's errors are significant
+     */
+    function isValid($include=false) {
         if (!is_array($this->_errors)) {
             $this->_errors = array();
             $this->getClean();
             foreach ($this->getFields() as $field)
-                if ($field->errors())
+                if ($field->errors() && (!$include || $include($field)))
                     $this->_errors[$field->get('id')] = $field->errors();
         }
         return !$this->_errors;
diff --git a/include/class.forms.php b/include/class.forms.php
index 6385f4190ca6d16f7b2f8834f419d4a471a66152..4250e258ce66b7dd3b29faf651ef82af1a85ddf1 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -53,12 +53,19 @@ class Form {
     function getInstructions() { return $this->instructions; }
     function getSource() { return $this->_source; }
 
-    function isValid() {
+    /**
+     * Validate the form and indicate if there no errors.
+     *
+     * Parameters:
+     * $filter - (callback) function to receive each field and return
+     *      boolean true if the field's errors are significant
+     */
+    function isValid($include=false) {
         if (!is_array($this->_errors)) {
             $this->_errors = array();
             $this->getClean();
             foreach ($this->getFields() as $field)
-                if ($field->errors())
+                if ($field->errors() && (!$include || $include($field)))
                     $this->_errors[$field->get('id')] = $field->errors();
         }
         return !$this->_errors;
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 82cc169a59eb019fe6c2d87a61f1052561f66586..5684d3f48395c43d4d375dd4ec97775e06c00644 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -1901,7 +1901,20 @@ class Ticket {
         }
 
         // Don't enforce form validation for email
-        if (!$form->isValid() && strtolower($origin) != 'email')
+        $field_filter = function($f) use ($origin) {
+            // Ultimately, only offer validation errors for web for
+            // non-internal fields. For email, no validation can be
+            // performed. For other origins, validate as usual
+            switch (strtolower($origin)) {
+            case 'email':
+                return false;
+            case 'web':
+                return !$f->get('private');
+            default:
+                return true;
+            }
+        };
+        if (!$form->isValid($field_filter))
             $errors += $form->errors();
 
         // Unpack dynamic variables into $vars for filter application