Accessing user's custom field in html.tpl.php
If you are using the global variable $user, it doesn't always contain a full initialized object. In fact, during the bootstrap, $user is initialized with the data contained in the "users" table, from the following code.

  if ($is_https) {
    $user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.ssid = :ssid", array(':ssid' =&gt; $sid))-&gt;fetchObject();
    if (!$user) {
      if (isset($_COOKIE[$insecure_session_name])) {
        $user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid AND s.uid = 0", array(
          ':sid' =&gt; $_COOKIE[$insecure_session_name],
        ))
        -&gt;fetchObject();
      }
    }
  }
  else {
    $user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid", array(':sid' =&gt; $sid))-&gt;fetchObject();
  }

  // We found the client's session record and they are an authenticated,
  // active user.
  if ($user &amp;&amp; $user-&gt;uid &gt; 0 &amp;&amp; $user-&gt;status == 1) {
    // This is done to unserialize the data member of $user.
    $user-&gt;data = unserialize($user-&gt;data);

    // Add roles element to $user.
    $user-&gt;roles = array();
    $user-&gt;roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
    $user-&gt;roles += db_query("SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = :uid", array(':uid' =&gt; $user-&gt;uid))-&gt;fetchAllKeyed(0, 1);
  }


If you want to be sure to get a fully loaded user object for the currently logged-in user, you should use the following code.

$account = user_uid_optional_load();


After that, you can get the value of any user field.

$fullname = field_get_items('user', $account, 'field_first_name');


You can also get the rendered value of the field using the following code.

$rendered_value = field_view_field('user', $account, 'field_first_name');


The other reason for which $user-&gt;field_first_name['und'][0]['value'] could not contain any value is that the language-neutral value of the field is not be set. ('und' is the value of the constant LANGUAGE_NONE, or LANGUAGE_NOT_SPECIFIED in Drupal 8.) If you use field_get_items(), or field_view_field(), you are sure to get the correct value.

As side note, it is preferable to keep the logic in the template.php file, in functions that are called from the template files.