How to fix auth/invalid-display-name: Display name must be non-empty string in Firebase

FirebaseBEGINNERLOWUpdated Dec 18, 2025· 106 views

This Firebase Authentication error occurs when attempting to set a user's display name with an empty string, null, or undefined value. The fix involves ensuring you always provide a valid non-empty string when setting the displayName property through createUser(), updateUser(), or updateProfile() methods.

Quick fix

Fixes auth/invalid-display-name

import { getAuth, updateProfile } from "firebase/auth";

const auth = getAuth();
const user = auth.currentUser;

async function updateUserDisplayName(newDisplayName) {
  // Validate before updating
  if (!newDisplayName || newDisplayName.trim().length === 0) {
    console.error('Display name cannot be empty');
    return { error: 'Please provide a valid display name' };
  }

  try {
    await updateProfile(user, {
      displayName: newDisplayName.trim() // Remove leading/trailing spaces
    });
    console.log('Display name updated successfully');
    return { success: true };
  } catch (error) {
    if (error.code === 'auth/invalid-display-name') {
      console.error('Invalid display name:', error.message);
    }
    return { error: error.message };
  }
}
  1. Validate displayName before passing to Firebase
  2. Fix user registration forms with proper validation
  3. Handle optional displayName correctly
  4. Fix common code patterns that cause this error
firebase — error
import { getAuth, updateProfile } from "firebase/auth";
const auth = getAuth();
const user = auth.currentUser;
async function updateUserDisplayName(newDisplayName) {
// Validate before updating
if (!newDisplayName || newDisplayName.trim().length === 0) {
console.error('Display name cannot be empty');
return { error: 'Please provide a valid display name' };
}
try {
await updateProfile(user, {
displayName: newDisplayName.trim() // Remove leading/trailing spaces
});
console.log('Display name updated successfully');
return { success: true };
} catch (error) {
if (error.code === 'auth/invalid-display-name') {
console.error('Invalid display name:', error.message);
}
return { error: error.message };
}
}
auth/invalid-display-name: Display name must be non-empty string

What this error means

The "auth/invalid-display-name" error in Firebase Authentication indicates that your application tried to set a user's display name with an invalid value. Firebase requires the displayName property to be either a non-empty string or omitted entirely. When you call Firebase Authentication methods like admin.auth().createUser(), admin.auth().updateUser(), or currentUser.updateProfile(), Firebase validates the displayName parameter. If you pass an empty string (""), null, undefined, or any non-string value, Firebase rejects the operation with this error. This validation exists because display names are meant to identify users in your application's UI. An empty or invalid display name could cause confusion or display issues. Firebase enforces this rule at the API level to maintain data integrity across all authentication methods.

Typical symptoms

  • Firebase Authentication operations fail with error code 'auth/invalid-display-name'
  • Error message states 'Display name must be non-empty string'
  • User creation or update operations fail unexpectedly
  • Error appears when calling updateProfile() with empty displayName
  • Admin SDK methods like createUser() or updateUser() throw this error
  • Previously working code breaks after adding displayName parameter
  • Firebase console shows authentication errors in logs

Common causes

  1. Passing an empty string ("") as the displayName value
  2. Setting displayName to null or undefined explicitly
  3. Using a variable that contains an empty string without validation
  4. Form input validation missing, allowing blank display names
  5. Passing displayName from user input without checking if it's filled
  6. Incorrect default values in user profile objects
  7. Copying code examples that don't validate displayName
  8. Type coercion converting null/undefined to empty string

How to fix "auth/invalid-display-name: Display name must be non-empty string"

1Validate displayName before passing to Firebase

Add validation to ensure displayName is never empty before calling Firebase methods:

Client-side validation (Web):

javascript
import { getAuth, updateProfile } from "firebase/auth";

const auth = getAuth();
const user = auth.currentUser;

async function updateUserDisplayName(newDisplayName) {
  // Validate before updating
  if (!newDisplayName || newDisplayName.trim().length === 0) {
    console.error('Display name cannot be empty');
    return { error: 'Please provide a valid display name' };
  }

  try {
    await updateProfile(user, {
      displayName: newDisplayName.trim() // Remove leading/trailing spaces
    });
    console.log('Display name updated successfully');
    return { success: true };
  } catch (error) {
    if (error.code === 'auth/invalid-display-name') {
      console.error('Invalid display name:', error.message);
    }
    return { error: error.message };
  }
}

Server-side validation (Admin SDK):

javascript
const admin = require('firebase-admin');

async function updateUserDisplayNameAdmin(uid, displayName) {
  // Validate before updating
  if (!displayName || typeof displayName !== 'string' || displayName.trim().length === 0) {
    throw new Error('Display name must be a non-empty string');
  }

  try {
    await admin.auth().updateUser(uid, {
      displayName: displayName.trim()
    });
    console.log('User display name updated');
  } catch (error) {
    if (error.code === 'auth/invalid-display-name') {
      console.error('Invalid display name provided');
    }
    throw error;
  }
}

Key validation points:
1. Check for null or undefined
2. Verify it's a string type
3. Ensure length > 0 after trimming whitespace
4. Trim leading/trailing spaces before saving

2Fix user registration forms with proper validation

Add validation to user registration and profile update forms:

HTML form with validation:

html
<form id="registration-form">
  <div>
    <label for="email">Email:</label>
    <input
      type="email"
      id="email"
      name="email"
      required
    />
  </div>

  <div>
    <label for="displayName">Display Name:</label>
    <input
      type="text"
      id="displayName"
      name="displayName"
      required
      minlength="1"
      maxlength="100"
      placeholder="Enter your name"
    />
    <span class="error" id="displayName-error"></span>
  </div>

  <div>
    <label for="password">Password:</label>
    <input
      type="password"
      id="password"
      name="password"
      required
    />
  </div>

  <button type="submit">Register</button>
</form>

JavaScript form handler:

javascript
import { getAuth, createUserWithEmailAndPassword, updateProfile } from "firebase/auth";

const auth = getAuth();
const form = document.getElementById('registration-form');

form.addEventListener('submit', async (e) => {
  e.preventDefault();

  const email = form.email.value;
  const password = form.password.value;
  const displayName = form.displayName.value.trim();

  // Validate display name
  const errorElement = document.getElementById('displayName-error');
  if (!displayName || displayName.length === 0) {
    errorElement.textContent = 'Display name is required';
    return;
  }

  if (displayName.length < 2) {
    errorElement.textContent = 'Display name must be at least 2 characters';
    return;
  }

  try {
    // Create user account
    const userCredential = await createUserWithEmailAndPassword(auth, email, password);

    // Update profile with display name
    await updateProfile(userCredential.user, {
      displayName: displayName
    });

    console.log('User registered with display name:', displayName);
    // Redirect to dashboard or show success message

  } catch (error) {
    if (error.code === 'auth/invalid-display-name') {
      errorElement.textContent = 'Please provide a valid display name';
    } else {
      errorElement.textContent = error.message;
    }
  }
});

React form with validation:

javascript
import { useState } from 'react';
import { getAuth, createUserWithEmailAndPassword, updateProfile } from "firebase/auth";

function RegistrationForm() {
  const [displayName, setDisplayName] = useState('');
  const [error, setError] = useState('');
  const auth = getAuth();

  const validateDisplayName = (name) => {
    if (!name || name.trim().length === 0) {
      return 'Display name is required';
    }
    if (name.trim().length < 2) {
      return 'Display name must be at least 2 characters';
    }
    return null;
  };

  const handleSubmit = async (e) => {
    e.preventDefault();

    const validationError = validateDisplayName(displayName);
    if (validationError) {
      setError(validationError);
      return;
    }

    try {
      const userCredential = await createUserWithEmailAndPassword(
        auth,
        email,
        password
      );

      await updateProfile(userCredential.user, {
        displayName: displayName.trim()
      });

      // Success - redirect or update UI
    } catch (error) {
      setError(error.message);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={displayName}
        onChange={(e) => setDisplayName(e.target.value)}
        placeholder="Display Name"
        required
      />
      {error && <span className="error">{error}</span>}
      <button type="submit">Register</button>
    </form>
  );
}
3Handle optional displayName correctly

If displayName is optional in your application, omit it entirely instead of passing empty values:

Incorrect approach (causes error):

javascript
// DON'T do this
await admin.auth().createUser({
  email: 'user@example.com',
  password: 'securePassword123',
  displayName: '' // This will cause auth/invalid-display-name
});

// DON'T do this either
await admin.auth().updateUser(uid, {
  displayName: null // This will also cause the error
});

Correct approach (omit empty values):

javascript
// Option 1: Build object conditionally
const userProperties = {
  email: 'user@example.com',
  password: 'securePassword123'
};

// Only add displayName if it has a value
if (displayName && displayName.trim().length > 0) {
  userProperties.displayName = displayName.trim();
}

await admin.auth().createUser(userProperties);
javascript
// Option 2: Use object spread with conditional property
const displayNameValue = 'John Doe'; // Could be empty string

await admin.auth().createUser({
  email: 'user@example.com',
  password: 'securePassword123',
  ...(displayNameValue && displayNameValue.trim().length > 0 && {
    displayName: displayNameValue.trim()
  })
});
javascript
// Option 3: Helper function for clean updates
function buildUserUpdateObject(updates) {
  const cleanUpdates = {};

  if (updates.email) cleanUpdates.email = updates.email;
  if (updates.password) cleanUpdates.password = updates.password;
  if (updates.displayName && updates.displayName.trim().length > 0) {
    cleanUpdates.displayName = updates.displayName.trim();
  }
  if (updates.photoURL) cleanUpdates.photoURL = updates.photoURL;

  return cleanUpdates;
}

// Usage
const updates = buildUserUpdateObject({
  displayName: userInput.displayName, // Could be empty
  photoURL: userInput.photoURL
});

await admin.auth().updateUser(uid, updates);

Key principle: If a field is optional, don't include it in the update object at all rather than passing empty/null values.

4Fix common code patterns that cause this error

Review and fix common patterns that inadvertently pass empty display names:

Pattern 1: Unvalidated form data

javascript
// WRONG - directly using form data without validation
const formData = new FormData(form);
await updateProfile(user, {
  displayName: formData.get('displayName') // Could be empty!
});

// CORRECT - validate first
const displayName = formData.get('displayName');
if (displayName && displayName.trim().length > 0) {
  await updateProfile(user, {
    displayName: displayName.trim()
  });
}

Pattern 2: Object destructuring with defaults

javascript
// WRONG - empty string as default
const { displayName = '' } = userData;
await admin.auth().updateUser(uid, { displayName });

// CORRECT - use undefined or check before using
const { displayName } = userData;
if (displayName && displayName.trim().length > 0) {
  await admin.auth().updateUser(uid, { displayName: displayName.trim() });
}

Pattern 3: API request handlers

javascript
// WRONG - trusting client input
app.post('/api/update-profile', async (req, res) => {
  const { displayName } = req.body;
  await admin.auth().updateUser(req.user.uid, { displayName });
});

// CORRECT - validate server-side
app.post('/api/update-profile', async (req, res) => {
  const { displayName } = req.body;

  if (!displayName || typeof displayName !== 'string' || displayName.trim().length === 0) {
    return res.status(400).json({
      error: 'Display name must be a non-empty string'
    });
  }

  try {
    await admin.auth().updateUser(req.user.uid, {
      displayName: displayName.trim()
    });
    res.json({ success: true });
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});

Pattern 4: Copying data from other auth providers

javascript
// WRONG - provider might not have displayName
const providerData = result.user.providerData[0];
await admin.auth().updateUser(uid, {
  displayName: providerData.displayName // Could be null!
});

// CORRECT - check existence first
const providerData = result.user.providerData[0];
if (providerData.displayName && providerData.displayName.length > 0) {
  await admin.auth().updateUser(uid, {
    displayName: providerData.displayName
  });
} else {
  console.log('Provider did not provide display name');
}
5Add defensive validation utilities

Create reusable validation utilities to prevent this error across your codebase:

Validation utility module:

javascript
// utils/firebase-validation.js

/**
 * Validates a display name for Firebase Authentication
 * @param {string} displayName - The display name to validate
 * @returns {object} Validation result with isValid and error properties
 */
export function validateDisplayName(displayName) {
  if (displayName === null || displayName === undefined) {
    return {
      isValid: false,
      error: 'Display name is required'
    };
  }

  if (typeof displayName !== 'string') {
    return {
      isValid: false,
      error: 'Display name must be a string'
    };
  }

  const trimmed = displayName.trim();

  if (trimmed.length === 0) {
    return {
      isValid: false,
      error: 'Display name cannot be empty'
    };
  }

  if (trimmed.length < 2) {
    return {
      isValid: false,
      error: 'Display name must be at least 2 characters'
    };
  }

  if (trimmed.length > 100) {
    return {
      isValid: false,
      error: 'Display name cannot exceed 100 characters'
    };
  }

  return {
    isValid: true,
    value: trimmed
  };
}

/**
 * Sanitizes user properties for Firebase Auth methods
 * Removes empty or invalid values
 */
export function sanitizeUserProperties(properties) {
  const sanitized = {};

  if (properties.email) {
    sanitized.email = properties.email;
  }

  if (properties.password) {
    sanitized.password = properties.password;
  }

  if (properties.displayName) {
    const validation = validateDisplayName(properties.displayName);
    if (validation.isValid) {
      sanitized.displayName = validation.value;
    }
  }

  if (properties.photoURL && properties.photoURL.trim().length > 0) {
    sanitized.photoURL = properties.photoURL.trim();
  }

  if (properties.phoneNumber) {
    sanitized.phoneNumber = properties.phoneNumber;
  }

  return sanitized;
}

Usage in your application:

javascript
import { validateDisplayName, sanitizeUserProperties } from './utils/firebase-validation';
import { getAuth, updateProfile } from 'firebase/auth';

const auth = getAuth();

async function updateUserProfile(displayName, photoURL) {
  // Validate display name
  const validation = validateDisplayName(displayName);

  if (!validation.isValid) {
    console.error(validation.error);
    return { error: validation.error };
  }

  try {
    // Safe to use validated value
    await updateProfile(auth.currentUser, {
      displayName: validation.value,
      photoURL: photoURL
    });
    return { success: true };
  } catch (error) {
    return { error: error.message };
  }
}

// Or use sanitize for batch updates
async function createUserAccount(userData) {
  const sanitized = sanitizeUserProperties(userData);

  try {
    await admin.auth().createUser(sanitized);
    return { success: true };
  } catch (error) {
    return { error: error.message };
  }
}

TypeScript type safety:

typescript
interface DisplayNameValidation {
  isValid: boolean;
  error?: string;
  value?: string;
}

export function validateDisplayName(displayName: unknown): DisplayNameValidation {
  // Implementation as above
}

Advanced notes

### Display Name Requirements and Limitations

Firebase displayName specifications:
- Must be a string type
- Cannot be empty string ("")
- Cannot be null or undefined when explicitly set
- Can contain any UTF-8 characters including emojis
- No enforced maximum length by Firebase, but recommended 100 characters or less
- Optional field - can be omitted entirely during user creation/updates

Character support:

javascript
// All of these are valid display names
const validNames = [
  "John Doe",           // Basic Latin
  "María García",       // Latin with accents
  "Владимир",           // Cyrillic
  "李明",               // Chinese characters
  "محمد",               // Arabic
  "John 🔥 Doe",        // With emoji
  "user_123",           // With numbers/underscores
  "O'Brien",            // With apostrophe
];

### Display Name vs Other User Properties

Comparison with other Firebase Auth properties:

| Property | Required | Can be empty | Validation |
|----------|----------|--------------|------------|
| email | Yes | No | Must be valid email format |
| password | Yes (for email/password) | No | Min 6 characters |
| displayName | No | No (if set) | Non-empty string |
| photoURL | No | No (if set) | Valid URL format |
| phoneNumber | No (for phone auth) | No | E.164 format |

### Common Integration Scenarios

Social login providers and displayName:

Different OAuth providers handle display names differently:

1. Google Sign-In: Always provides displayName from Google account
2. Facebook Login: Provides name, but may require permissions
3. GitHub: Provides name if set in GitHub profile
4. Apple Sign-In: May not provide name if user opts out
5. Twitter: Provides display name from Twitter profile

Handling provider differences:

javascript
import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";

const auth = getAuth();

async function signInAndEnsureDisplayName(provider) {
  const result = await signInWithPopup(auth, provider);
  const user = result.user;

  // Check if provider gave us a display name
  if (!user.displayName || user.displayName.trim().length === 0) {
    // Prompt user to set display name
    const customName = await promptUserForDisplayName();

    if (customName && customName.trim().length > 0) {
      await updateProfile(user, {
        displayName: customName.trim()
      });
    }
  }

  return user;
}

### Security and Privacy Considerations

Display name as user-facing content:
Display names are often shown publicly in your application, so consider:

1. XSS prevention: Firebase doesn't sanitize displayName content

javascript
// Always escape when displaying
   import DOMPurify from 'dompurify';

   const safeDisplayName = DOMPurify.sanitize(user.displayName);

2. Content moderation: Implement profanity filtering if needed

javascript
import Filter from 'bad-words';
   const filter = new Filter();

   function validateAndCleanDisplayName(name) {
     if (!name || name.trim().length === 0) {
       return { error: 'Display name required' };
     }

     const cleaned = name.trim();

     if (filter.isProfane(cleaned)) {
       return { error: 'Display name contains inappropriate content' };
     }

     return { value: cleaned };
   }

3. Length limits: Consider UX when displaying long names
4. Uniqueness: displayName is NOT unique - don't use for identification

Privacy considerations:
- Users may not want to use real names
- Consider allowing usernames separate from displayName
- Provide option to change displayName easily
- Don't require sensitive information in display names

### Migration and Backward Compatibility

Handling existing users without display names:

javascript
// Check and update users missing display names
async function migrateUsersWithoutDisplayNames() {
  const listUsersResult = await admin.auth().listUsers(1000);

  for (const userRecord of listUsersResult.users) {
    if (!userRecord.displayName || userRecord.displayName.trim().length === 0) {
      // Generate default display name from email
      const defaultName = userRecord.email?.split('@')[0] || 'User';

      try {
        await admin.auth().updateUser(userRecord.uid, {
          displayName: defaultName
        });
        console.log(`Updated user ${userRecord.uid} with display name: ${defaultName}`);
      } catch (error) {
        console.error(`Failed to update user ${userRecord.uid}:`, error);
      }
    }
  }
}

### Testing Display Name Validation

Unit tests for validation:

javascript
describe('validateDisplayName', () => {
  test('rejects empty string', () => {
    const result = validateDisplayName('');
    expect(result.isValid).toBe(false);
  });

  test('rejects null', () => {
    const result = validateDisplayName(null);
    expect(result.isValid).toBe(false);
  });

  test('rejects undefined', () => {
    const result = validateDisplayName(undefined);
    expect(result.isValid).toBe(false);
  });

  test('trims whitespace', () => {
    const result = validateDisplayName('  John Doe  ');
    expect(result.isValid).toBe(true);
    expect(result.value).toBe('John Doe');
  });

  test('accepts valid names', () => {
    const result = validateDisplayName('John Doe');
    expect(result.isValid).toBe(true);
    expect(result.value).toBe('John Doe');
  });
});

### Error Recovery Strategies

Graceful degradation when displayName is unavailable:

javascript
function getUserDisplayText(user) {
  // Fallback chain
  return user.displayName ||
         user.email?.split('@')[0] ||
         user.phoneNumber ||
         'Anonymous User';
}

// Usage in UI
function UserProfile({ user }) {
  const displayText = getUserDisplayText(user);

  return (
    <div>
      <h2>{displayText}</h2>
      {!user.displayName && (
        <p>
          <a href="/profile/edit">Set your display name</a>
        </p>
      )}
    </div>
  );
}

Frequently asked questions

What does "auth/invalid-display-name" mean?
The "auth/invalid-display-name" error in Firebase Authentication indicates that your application tried to set a user's display name with an invalid value. Firebase requires the displayName property to be either a non-empty string or omitted entirely. updateProfile(), Firebase validates the displayName parameter.
How do I fix "auth/invalid-display-name"?
This Firebase Authentication error occurs when attempting to set a user's display name with an empty string, null, or undefined value. The fix involves ensuring you always provide a valid non-empty string when setting the displayName property through createUser(), updateUser(), or updateProfile() methods.
What causes "auth/invalid-display-name"?
Passing an empty string ("") as the displayName value Setting displayName to null or undefined explicitly Using a variable that contains an empty string without validation
Is the "auth/invalid-display-name" error serious?
It is a low-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading