How to fix messaging/SENDER_ID_MISMATCH: Registration token tied to different sender in Firebase

FirebaseINTERMEDIATEMEDIUMUpdated Dec 12, 2025· 223 views

This Firebase Cloud Messaging error occurs when a registration token (FCM token) is being used with a different sender ID than the one it was originally created for. The token is permanently tied to its original sender ID and cannot be used with other Firebase projects.

Quick fix

Fixes messaging/SENDER_ID_MISMATCH: Registration token tied to different sender

// Initialize Firebase Admin SDK with correct service account
const admin = require('firebase-admin');

// Method 1: Using environment variable (recommended for production)
admin.initializeApp({
  credential: admin.credential.applicationDefault(),
  projectId: 'your-correct-project-id' // Verify this matches token source
});

// Method 2: Using service account JSON file
const serviceAccount = require('./path/to/serviceAccountKey.json');
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

// Verify the project ID
console.log('Current project ID:', admin.app().options.projectId);

// Compare with where tokens were generated:
// - Check client app's google-services.json (Android)
// - Check client app's GoogleService-Info.plist (iOS)
// - Check web app's firebase config
  1. Verify your Firebase project configuration matches
  2. Refresh registration tokens on client devices
  3. Check and update client-side Firebase configuration
  4. Implement token validation and cleanup on server
firebase — error
// Initialize Firebase Admin SDK with correct service account
const admin = require('firebase-admin');
// Method 1: Using environment variable (recommended for production)
admin.initializeApp({
credential: admin.credential.applicationDefault(),
projectId: 'your-correct-project-id' // Verify this matches token source
});
// Method 2: Using service account JSON file
const serviceAccount = require('./path/to/serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
// Verify the project ID
console.log('Current project ID:', admin.app().options.projectId);
// Compare with where tokens were generated:
// - Check client app's google-services.json (Android)
// - Check client app's GoogleService-Info.plist (iOS)
// - Check web app's firebase config
messaging/SENDER_ID_MISMATCH: Registration token tied to different sender

What this error means

The "messaging/SENDER_ID_MISMATCH" error in Firebase Cloud Messaging (FCM) indicates that you're trying to use a registration token with a Firebase project that differs from the one the token was originally generated for. Each FCM registration token is cryptographically tied to a specific sender ID (which corresponds to a Firebase project) at creation time. When a mobile app registers with FCM, it receives a token that's uniquely associated with: 1. The specific Firebase project (identified by its sender ID) 2. The specific app instance/device 3. The specific app package/bundle identifier This binding is permanent - tokens cannot be transferred between Firebase projects. If you attempt to send a message using a token from Project A through Project B's credentials, FCM rejects it with this error to prevent cross-project message delivery. This error commonly occurs during development when switching between Firebase projects, or in production when migrating apps between projects without proper token refresh.

Typical symptoms

  • Push notifications fail with "SENDER_ID_MISMATCH" error when sending messages
  • HTTP 400 response from FCM API with error code "messaging/SENDER_ID_MISMATCH"
  • Messages work in development but fail in production (or vice versa)
  • Error appears after switching Firebase project configurations
  • Tokens that previously worked suddenly start failing with this error

Common causes

  1. Using tokens from one Firebase project with credentials from a different project
  2. Switching between development and production Firebase projects without refreshing tokens
  3. Migrating app to a new Firebase project without updating client-side token generation
  4. Incorrect Firebase configuration (google-services.json or GoogleService-Info.plist) on client
  5. Server using wrong Firebase Admin SDK credentials for the project tokens belong to
  6. Testing with tokens from live/production app on staging/development Firebase project

How to fix "messaging/SENDER_ID_MISMATCH: Registration token tied to different sender"

1Verify your Firebase project configuration matches

Check that your server-side Firebase Admin SDK is configured with the correct project credentials that match where the tokens were generated:

javascript
// Initialize Firebase Admin SDK with correct service account
const admin = require('firebase-admin');

// Method 1: Using environment variable (recommended for production)
admin.initializeApp({
  credential: admin.credential.applicationDefault(),
  projectId: 'your-correct-project-id' // Verify this matches token source
});

// Method 2: Using service account JSON file
const serviceAccount = require('./path/to/serviceAccountKey.json');
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

// Verify the project ID
console.log('Current project ID:', admin.app().options.projectId);

// Compare with where tokens were generated:
// - Check client app's google-services.json (Android)
// - Check client app's GoogleService-Info.plist (iOS)
// - Check web app's firebase config

Ensure the project ID in your server configuration matches the project where client apps are registered.

2Refresh registration tokens on client devices

When switching Firebase projects, you must refresh tokens on all client devices:

javascript
// On client (Android/iOS/Web), get a fresh token
// Example for web:
import { getMessaging, getToken } from "firebase/messaging";

const messaging = getMessaging();

// Request permission and get token
async function requestPermissionAndGetToken() {
  try {
    const permission = await Notification.requestPermission();
    if (permission === 'granted') {
      const token = await getToken(messaging, {
        vapidKey: 'YOUR_VAPID_KEY' // From Firebase Console > Cloud Messaging
      });

      console.log('New FCM token:', token);

      // Send this new token to your server
      await sendTokenToServer(token);

      return token;
    }
  } catch (error) {
    console.error('Error getting token:', error);
  }
}

// For existing apps, you can also listen for token refresh:
import { onTokenRefresh } from "firebase/messaging";

onTokenRefresh(messaging, () => {
  getToken(messaging).then((refreshedToken) => {
    console.log('Token refreshed:', refreshedToken);
    sendTokenToServer(refreshedToken);
  });
});

Old tokens from the previous project will continue to fail with SENDER_ID_MISMATCH.

3Check and update client-side Firebase configuration

Verify the client app is configured for the correct Firebase project:

For Android (google-services.json):

json
{
  "project_info": {
    "project_number": "123456789012",  // This is the sender ID
    "project_id": "your-project-id",
    "storage_bucket": "your-project-id.appspot.com"
  },
  "client": [...],
  "configuration_version": "1"
}

For iOS (GoogleService-Info.plist):

xml
<key>PROJECT_ID</key>
<string>your-project-id</string>
<key>GOOGLE_APP_ID</key>
<string>1:123456789012:ios:abc123def456</string>

For web (firebase config):

javascript
const firebaseConfig = {
  apiKey: "your-api-key",
  authDomain: "your-project-id.firebaseapp.com",
  projectId: "your-project-id",  // Must match server project
  storageBucket: "your-project-id.appspot.com",
  messagingSenderId: "123456789012",  // This is the sender ID
  appId: "1:123456789012:web:abc123def456"
};

The messagingSenderId (also called project number) must match between client and server.

4Implement token validation and cleanup on server

Add server-side validation to detect and handle mismatched tokens:

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

async function sendMessageWithValidation(token, message) {
  try {
    const response = await admin.messaging().send({
      token: token,
      notification: {
        title: message.title,
        body: message.body
      }
    });

    console.log('Message sent successfully:', response);
    return { success: true, response };

  } catch (error) {
    console.error('Error sending message:', error.message);

    // Check for SENDER_ID_MISMATCH specifically
    if (error.code === 'messaging/sender-id-mismatch' ||
        error.message.includes('SENDER_ID_MISMATCH')) {

      console.log('Token belongs to different project:', token);

      // Remove this token from your database
      await removeInvalidTokenFromDatabase(token);

      // Optionally notify client to refresh token
      await notifyClientToRefreshToken(token);

      return {
        success: false,
        error: 'SENDER_ID_MISMATCH',
        action: 'token_removed'
      };
    }

    // Handle other errors
    return { success: false, error: error.message };
  }
}

// Helper function to remove invalid token
async function removeInvalidTokenFromDatabase(token) {
  // Remove from your database/Redis cache
  await db.tokens.deleteOne({ token: token });
  console.log('Removed invalid token from database');
}

// Helper to notify client (if you have a way to communicate back)
async function notifyClientToRefreshToken(token) {
  // Could use other channels like WebSockets, database flags, etc.
  // This depends on your app architecture
}
5Test with token validation API

Use Firebase Admin SDK to validate tokens before sending messages:

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

async function validateToken(token) {
  try {
    // This will fail if token is from different project
    const info = await admin.messaging().getRegistrationTokenInfo(token);

    console.log('Token is valid:', {
      projectId: info.projectId,
      appId: info.appId,
      platform: info.platform,
      token: token.substring(0, 20) + '...' // Log partial for security
    });

    return { valid: true, info };

  } catch (error) {
    if (error.code === 'messaging/sender-id-mismatch') {
      console.log('Token belongs to different project');
      return { valid: false, reason: 'SENDER_ID_MISMATCH' };
    }

    console.error('Token validation error:', error.message);
    return { valid: false, reason: error.code };
  }
}

// Usage: Validate tokens before storing or using them
const token = 'your-fcm-token';
const validation = await validateToken(token);

if (!validation.valid) {
  if (validation.reason === 'SENDER_ID_MISMATCH') {
    console.log('Do not store this token - it's from wrong project');
    // Prompt user to re-register for notifications
  }
}

This proactive validation helps prevent storing invalid tokens.

6Handle project migration properly

If migrating between Firebase projects, follow this sequence:

1. Prepare new project:
- Create new Firebase project
- Configure Cloud Messaging
- Get new VAPID key (for web) and configuration files

2. Update client apps gradually:
- Release app update with new Firebase configuration
- Implement dual-token support during transition
- Listen for new tokens and send to server

3. Server-side transition:

javascript
// Support both old and new projects during migration
   const adminOld = require('firebase-admin');
   const adminNew = require('firebase-admin');

   // Initialize two app instances
   const oldApp = adminOld.initializeApp(
     oldServiceAccount,
     'old-project'
   );

   const newApp = adminNew.initializeApp(
     newServiceAccount,
     'new-project'
   );

   // Determine which project to use based on token
   async function sendMessage(token, message) {
     // Try new project first (most tokens should be new)
     try {
       const messaging = newApp.messaging();
       return await messaging.send({ token, ...message });
     } catch (error) {
       if (error.code === 'messaging/sender-id-mismatch') {
         // Token belongs to old project
         const messaging = oldApp.messaging();
         return await messaging.send({ token, ...message });
       }
       throw error;
     }
   }

4. Cleanup:
- Monitor token migration progress
- Remove old project configuration once all tokens migrated
- Update server to use only new project

Advanced notes

### Understanding Sender ID Binding

Technical Details:
- Each FCM token contains an embedded signature tied to the sender ID (project number)
- The binding happens during token generation on the client device
- Firebase servers verify this signature on every message send
- This prevents token theft/reuse across different projects

Common Migration Scenarios:

1. Development to Production:
- Development app uses dev Firebase project
- Production app must use production Firebase project
- Tokens cannot be shared between these environments

2. Project Consolidation:
- Multiple apps moving to single Firebase project
- Each app needs fresh tokens from the consolidated project
- Old tokens from individual projects become invalid

3. Rebranding/Re-publishing:
- App package name changes require new Firebase project
- New package = new Firebase project = new tokens required

### Token Lifecycle Management

Best Practices:
1. Store project context with tokens: Record which Firebase project each token belongs to
2. Regular token refresh: Implement periodic token refresh (FCM does this automatically every ~6 months)
3. Validation before storage: Validate tokens match current project before storing in database
4. Cleanup invalid tokens: Remove tokens that fail with SENDER_ID_MISMATCH

Monitoring and Alerts:
- Track SENDER_ID_MISMATCH error rates
- Alert if error rate spikes (indicates configuration issue)
- Monitor token migration progress during project transitions

### Security Implications

The SENDER_ID_MISMATCH error is a security feature that:
- Prevents token reuse across projects
- Ensures messages only go to intended recipients
- Maintains project isolation in multi-tenant environments

Never attempt to "fix" this by modifying tokens or bypassing validation - instead, ensure proper project alignment.

Frequently asked questions

What does "messaging/SENDER_ID_MISMATCH: Registration token tied to different sen" mean?
The "messaging/SENDER_ID_MISMATCH" error in Firebase Cloud Messaging (FCM) indicates that you're trying to use a registration token with a Firebase project that differs from the one the token was originally generated for. Each FCM registration token is cryptographically tied to a specific sender ID (which corresponds to a Firebase project) at creation time. When a mobile app registers with FCM, it receives a token that's uniquely associated with: 1.
How do I fix "messaging/SENDER_ID_MISMATCH: Registration token tied to different sen"?
This Firebase Cloud Messaging error occurs when a registration token (FCM token) is being used with a different sender ID than the one it was originally created for. The token is permanently tied to its original sender ID and cannot be used with other Firebase projects.
What causes "messaging/SENDER_ID_MISMATCH: Registration token tied to different sen"?
Using tokens from one Firebase project with credentials from a different project Switching between development and production Firebase projects without refreshing tokens Migrating app to a new Firebase project without updating client-side token generation
Is the "messaging/SENDER_ID_MISMATCH: Registration token tied to different sen" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading