Why required form field has #required=FALSE on theme level?
In short, the hidden input field that stores the file ID (fid) is what is required, but the displayed file upload element isn't. The actual "displayed" element is added to that form element in file_managed_file_process() in file.module. Specifically, check out line 440 of that file:

  // The file upload field itself.
  $element['upload'] = array(
    '#name' =&gt; 'files[' . implode('_', $element['#parents']) . ']',
    '#type' =&gt; 'file',
    '#title' =&gt; t('Choose a file'),
    '#title_display' =&gt; 'invisible',
    '#size' =&gt; $element['#size'],
    '#theme_wrappers' =&gt; array(),
    '#weight' =&gt; -10,
  );


This has no #required property, and so therefore defaults to FALSE. If you dpm() your element earlier in the process (before it's expanded to include more hidden elements and attach the necessary javascript and CSS to be a full-fledged "managed file" element) you'll see your #required =&gt; TRUE.

I would add an additional function to the #process property of your form element, which will run after file_managed_file_process(). In it, you can check if the original element had #required =&gt; TRUE and then also set that on the $element['upload'] item. I haven't tried it, but I think that would get you what you want.

Edit: It would be wiser to do this in #after_build and not just append to #process. Here's an example:

&lt;?php

function my_form_builder($form, &amp;$form_state) {
  $form['file'] = array(
    '#type' =&gt; 'managed_file',
    '#title' =&gt; 'Upload a File',
    '#required' =&gt; TRUE,
    '#after_build' =&gt; array('my_file_element_after_build')
  );

  return $form;
}

function my_file_element_after_build($element, &amp;$form_state) {
  // Set the 'file' element to have the same #required property as its original form element.
  $element['upload']['#required'] = $element['#required'];
  return $element;
}

?&gt;