I've build a form where the user can upload an image as avatar for his profile. But I have an issue as the selected image is not being recognized at all.

I used the image example from drupal.org, this is my minimal code not working at all:

function my_edit_form($form, $form_state, $entity) {

  $form['picture']['picture_upload'] = array(
    '#type' => 'file',
    '#title' => t("Upload picture"),
    '#description' => t("Your virtual face or picture. Pictures larger than 150x150 pixels will be scaled down."),
    '#upload_location' => 'public://pictures/',
    '#size' => 48,

  return $form;

upload picture form

Now, I'm trying to use the file() functions as described in the documentation but it seems my $form_state['values']['picture'] is always NULL.

function my_edit_form_submit($form, &$form_state) {

devel form state values output

I have no idea how that's possible and I'm a bit lost here. Any idea what else I could try?

  • I would recommend you use managed_file as form element instead, please see drupal.stackexchange.com/questions/25516/… for reference. As for your code it is the element picture_upload that will hold the actual value and not picture but I can't see now directly what's wrong, sorry :( – Pontus Nilsson Jun 16 '14 at 12:52
  • #upload_location is also only valid for managed_file elements... – Clive Jun 16 '14 at 12:57

Okay, this is tricky how Drupal handles the file uploads and took me some time to figure out.

$form_state indeed shows NULL or empty strings or empty arrays for my file upload unless I add a proper upload function. The file exists but is not uploaded yet.

It's worth taking a look at user_validate_picture():

function user_validate_picture(&$form, &$form_state) {
  // If required, validate the uploaded picture.
  $validators = array(
    'file_validate_is_image' => array(),
    'file_validate_image_resolution' => array(variable_get('user_picture_dimensions', '85x85')),
    'file_validate_size' => array(variable_get('user_picture_file_size', '30') * 1024),

  // Save the file as a temporary file.
  $file = file_save_upload('picture_upload', $validators);
  if ($file === FALSE) {
    form_set_error('picture_upload', t("Failed to upload the picture image; the %directory directory doesn't exist or is not writable.", array('%directory' => variable_get('user_picture_path', 'pictures'))));
  elseif ($file !== NULL) {
    $form_state['values']['picture_upload'] = $file;

Calling this function from inside my own validation function will upload the file to temporary://What-is-Sustainability_0.png and it's now visible in $form_state['values']:

form state including picture

This is what I was looking for, now I can simply save the file where I need it and have the fid available to link it to entities.


For Drupal 8:

public function validateForm(array &$form, FormStateInterface $form_state){

    parent::validateForm($form, $form_state);

    $validators = array(
        'file_validate_extensions' => array("pdf"),
        'file_validate_size' => array(file_upload_max_size()),

    // Save the file as a temporary file.
    $file = file_save_upload('field_upload', $validators, FALSE, 0, FILE_EXISTS_REPLACE);
    if ($file === FALSE) {
        $form_state->setError($form["field_upload"], "Failed to upload the file");
    elseif ($file !== NULL) {

        $form_state->setValue("field_upload", $file->toArray());


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.