diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index d5d12bea93f519e3b443038fbcdda61f35615566..d8fccf5dc451aa81a673e56627f00e7c82e25854 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -609,7 +609,7 @@ class TicketsAjaxAPI extends AjaxController {
 
         $state = strtolower($status->getState());
 
-        if (!$errors && $ticket->setStatus($status, $_REQUEST['comments'])) {
+        if (!$errors && $ticket->setStatus($status, $_REQUEST['comments'], $errors)) {
 
             if ($state == 'deleted') {
                 $msg = sprintf('%s %s',
@@ -723,13 +723,15 @@ class TicketsAjaxAPI extends AjaxController {
                 if (($ticket=Ticket::lookup($tid))
                         && $ticket->getStatusId() != $status->getId()
                         && $ticket->checkStaffAccess($thisstaff)
-                        && $ticket->setStatus($status, $comments))
+                        && $ticket->setStatus($status, $comments, $errors))
                     $i++;
             }
 
-            if (!$i)
-                $errors['err'] = sprintf(__('Unable to change status for %s'),
+            if (!$i) {
+                $errors['err'] = $errors['err']
+                    ?: sprintf(__('Unable to change status for %s'),
                         _N('the selected ticket', 'any of the selected tickets', $count));
+            }
             else {
                 // Assume success
                 if ($i==$count) {
diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index 3620cc1e87535dd3c3ead353676009d2554077d3..d2cee5573987e0cde80c3c7f1a1bcacc98a9f703 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -622,6 +622,9 @@ class DynamicFormField extends VerySimpleModel {
     function isRequiredForUsers() {
         return $this->hasFlag(self::FLAG_CLIENT_REQUIRED);
     }
+    function isRequiredForClose() {
+        return $this->hasFlag(self::FLAG_CLOSE_REQUIRED);
+    }
     function isEditableToStaff() {
         return $this->hasFlag(self::FLAG_ENABLED)
             && $this->hasFlag(self::FLAG_AGENT_EDIT);
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 33400acbd1d1093cee4855b1827d0918cb821a36..5bdec7646de19b257870924cdfdcdf90b8bddb6f 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -801,6 +801,26 @@ class Ticket {
         }
     }
 
+    function getMissingRequiredFields() {
+        $returnArray = array();
+        $forms=DynamicFormEntry::forTicket($this->getId());
+        foreach ($forms as $form) {
+            foreach ($form->getFields() as $field) {
+                if ($field->isRequiredForClose()) {
+                    if (!($field->answer->get('value'))) {
+                        array_push($returnArray, $field->get('label'));
+                    }
+                }
+            }
+        }
+        return $returnArray;
+    }
+
+    function getMissingRequiredField() {
+        $fields = $this->getMissingRequiredFields();
+        return $fields[0];
+    }
+
     function addCollaborator($user, $vars, &$errors) {
 
         if (!$user || $user->getId()==$this->getOwnerId())
@@ -957,7 +977,7 @@ class Ticket {
     }
 
     //Status helper.
-    function setStatus($status, $comments='') {
+    function setStatus($status, $comments='', &$errors=array()) {
         global $thisstaff;
 
         if ($status && is_numeric($status))
@@ -979,6 +999,12 @@ class Ticket {
         $ecb = null;
         switch($status->getState()) {
             case 'closed':
+                if ($this->getMissingRequiredFields()) {
+                    $errors['err'] = sprintf(__(
+                        'This ticket is missing data on %s one or more required fields %s and cannot be closed'),
+                    '', '');
+                    return false;
+                }
                 $sql.=', closed=NOW(), lastupdate=NOW(), duedate=NULL ';
                 if ($thisstaff)
                     $sql.=', staff_id='.db_input($thisstaff->getId());
diff --git a/include/staff/templates/dynamic-form.tmpl.php b/include/staff/templates/dynamic-form.tmpl.php
index 4efb94a218fc3d789693511306f2bee093020fbb..8d725dece67078da3e8fbba1b7578fc84e32d4ab 100644
--- a/include/staff/templates/dynamic-form.tmpl.php
+++ b/include/staff/templates/dynamic-form.tmpl.php
@@ -50,7 +50,7 @@ if (isset($options['entry']) && $options['mode'] == 'edit') { ?>
                 <?php
             }
             else { ?>
-                <td class="multi-line <?php if ($field->isRequiredForStaff()) echo 'required';
+                <td class="multi-line <?php if ($field->isRequiredForStaff() || $field->isRequiredForClose()) echo 'required';
                 ?>" style="min-width:120px;" <?php if ($options['width'])
                     echo "width=\"{$options['width']}\""; ?>>
                 <?php echo Format::htmlchars($field->getLocal('label')); ?>:</td>
@@ -77,6 +77,12 @@ if (isset($options['entry']) && $options['mode'] == 'edit') { ?>
                 ?>" data-entry-id="<?php echo $field->getAnswer()->get('entry_id');
                 ?>"> <i class="icon-trash"></i> </a></div><?php
             }
+            if (!$a->getValue() && $field->isRequiredForClose()) {
+?><i class="icon-warning-sign help-tip warning"
+    data-title="<?php echo __('Required to close ticket'); ?>"
+    data-content="<?php echo __('Data is required in this field in order to close the related ticket'); ?>"
+/></i><?php
+            }
             if ($field->get('hint') && !$field->isBlockLevel()) { ?>
                 <br /><em style="color:gray;display:inline-block"><?php
                     echo Format::htmlchars($field->getLocal('hint')); ?></em>
diff --git a/include/staff/templates/status-options.tmpl.php b/include/staff/templates/status-options.tmpl.php
index cdcaa395bec9a424a61f6bf62f9b4a29f0ef58b2..c82696e6ff2e052dd84294afb6586233ae7fa5b8 100644
--- a/include/staff/templates/status-options.tmpl.php
+++ b/include/staff/templates/status-options.tmpl.php
@@ -12,6 +12,23 @@ $actions= array(
             'action' => 'reopen'
             ),
         );
+
+$states = array('open');
+if ($thisstaff->canCloseTickets() && (!$ticket || !$ticket->getMissingRequiredFields()))
+    $states = array_merge($states, array('closed'));
+
+$statusId = $ticket ? $ticket->getStatusId() : 0;
+$nextStatuses = array();
+foreach (TicketStatusList::getStatuses(
+            array('states' => $states)) as $status) {
+    if (!isset($actions[$status->getState()])
+            || $statusId == $status->getId())
+        continue;
+    $nextStatuses[] = $status;
+}
+
+if (!$nextStatuses)
+    return;
 ?>
 
 <span
@@ -26,18 +43,7 @@ $actions= array(
 <div id="action-dropdown-statuses"
     class="action-dropdown anchor-right">
     <ul>
-    <?php
-    $states = array('open');
-    if ($thisstaff->canCloseTickets())
-        $states = array_merge($states, array('closed'));
-
-    $statusId = $ticket ? $ticket->getStatusId() : 0;
-    foreach (TicketStatusList::getStatuses(
-                array('states' => $states))->all() as $status) {
-        if (!isset($actions[$status->getState()])
-                || $statusId == $status->getId())
-            continue;
-        ?>
+<?php foreach ($nextStatuses as $status) { ?>
         <li>
             <a class="no-pjax <?php
                 echo $ticket? 'ticket-action' : 'tickets-action'; ?>"
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index 74f819e0d70663c78b1c3d74d4d09e3ae03b1730..207d573c5da4c312a1f7ba9448167cfb2a7dec72 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -605,15 +605,23 @@ print $response_form->getField('attachments')->render();
                 </td>
             </tr>
             <tr>
-                <td width="120">
+                <td width="120" style="vertical-align:top">
                     <label><strong><?php echo __('Ticket Status');?>:</strong></label>
                 </td>
                 <td>
+                    <?php
+                    if ($outstanding = $ticket->getMissingRequiredFields()) { ?>
+                    <div class="warning-banner"><?php echo sprintf(__(
+                        'This ticket is missing data on %s one or more required fields %s and cannot be closed'),
+                        "<a href=\"tickets.php?id={$ticket->getId()}&a=edit\">",
+                        '</a>'
+                    ); ?></div>
+<?php               } ?>
                     <select name="reply_status_id">
                     <?php
                     $statusId = $info['reply_status_id'] ?: $ticket->getStatusId();
                     $states = array('open');
-                    if ($thisstaff->canCloseTickets())
+                    if ($thisstaff->canCloseTickets() && !$outstanding)
                         $states = array_merge($states, array('closed'));
 
                     foreach (TicketStatusList::getStatuses(
diff --git a/scp/css/scp.css b/scp/css/scp.css
index 6bbdcc8abcd61d9e67e4f5fbf7a19ec4aff505a0..b97e1cc2bcfdc37b4a840095165b790d043311dc 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -2018,7 +2018,8 @@ button a:hover {
     font-style: italic;
 }
 
-.form_table tr:hover i.help-tip {
+.form_table tr:hover i.help-tip,
+.form_table tr i.help-tip.warning {
     opacity: 1;
     color: #ffc20f;
 }