Adding accept attribute to managed_file field to specify file types client-side I've got a Drupal 7 file field in a custom form like this:
  $form['image_upload'] = array(
    '#type' =&gt; 'managed_file',
    '#title' =&gt; t('Image upload'),
    '#description' =&gt; t('Upload png images'),
    '#upload_location' =&gt; 'public://',
    '#process' =&gt; array('file_managed_file_process'),
    '#attributes' =&gt; array('accept' =&gt; '.png'),
  );

As you can see I've added an #attributes array setting the &quot;accept&quot;.

The accept value doesn't show up in the resulting HTML. I'm surprised it isn't at least set somewhere.
If I change the array key from accept to class then it shows up on the parent div and not on the input element where I expect it.

So, it seems like there are 2 problems to overcome to get to use this feature.
Still not sure if this is a bona fide bug; the file_managed element has several elements inside it, so there's no real way to specify which of those you're targeting with the #attributes property. 

So in one respect it does make sense that they'd be ignored, because of the ambiguity. But it works for classes, so it makes less sense. Would need a bit more digging to find out why I suspect.

Either way, you can work around it by adding your own process callback to the element:

$form['image_upload'] = array(
  '#type' =&gt; 'managed_file',
  '#title' =&gt; t('Image upload'),
  '#description' =&gt; t('Upload png images'),
  '#upload_location' =&gt; 'public://',
  '#process' =&gt; array('file_managed_file_process', 'MYMODULE_file_managed_file_process'),
);

function MYMODULE_file_managed_file_process($element) {
  $element['upload']['#attributes']['accept'] = '.jpg';
  return $element;
}