Your push send returns 404 UNREGISTERED, “Requested entity was not found” or messaging/registration-token-not-registered. The message didn't fail because of your payload: FCM is telling you that device token no longer works. The fix is to delete it, and to stop dead tokens building up.
What the error looks like
This is the response from the FCM HTTP v1 API:
{
"error": {
"code": 404,
"message": "Requested entity was not found.",
"status": "NOT_FOUND",
"details": [
{
"@type": "type.googleapis.com/google.firebase.fcm.v1.FcmError",
"errorCode": "UNREGISTERED"
}
]
}
}The Firebase Admin SDK for Node.js reports the same thing as messaging/registration-token-not-registered. Other SDKs have their own names for it, so check the errorCode or the SDK's docs rather than matching the message text.
Why a token stops working
- The app was uninstalled, or the token was invalidated on the device.
- The token was replaced. Tokens can change, for example after a reinstall or when your app calls
deleteToken(), and your server may still hold the old one. - The token expired. On Android, Firebase treats a registration as expired after 270 days of inactivity.
- APNs rejected the token on iOS. Firebase relies on APNs there, so an invalid APNs token can surface as the same error.
- The token string was changed. A token that was cut short or altered when stored can fail, so save it exactly as you received it.
How to fix it
- Delete the token when FCM says it's dead. Check each result in a batch, because one bad token doesn't fail the others.
- Don't retry it. Retries only waste sends. Save retries for temporary errors.
- Send the new token to your server. Upload it on app start and whenever it refreshes.
- Store a timestamp with each token, and update it on every upload, so you can see which ones are stale.
- Remove stale tokens on a schedule. Firebase's default definition of stale is more than a month without connecting to FCM, and it suggests refreshing tokens about once a month. Choose a window that suits your app.
Here's step 1 with the Firebase Admin SDK for Node.js:
import { getMessaging } from "firebase-admin/messaging";
const TOKEN_IS_DEAD = "messaging/registration-token-not-registered";
export async function sendToTokens(tokens, notification) {
const result = await getMessaging().sendEachForMulticast({ tokens, notification });
const deadTokens = [];
result.responses.forEach((response, i) => {
if (!response.success && response.error?.code === TOKEN_IS_DEAD) {
deadTokens.push(tokens[i]);
}
});
// Your own function: delete these tokens from your database
await removeTokens(deadTokens);
}When it's a different FCM error
Only delete tokens for the errors that call for it. These need a different fix:
| Error | HTTP | What it means | What to do |
|---|---|---|---|
UNREGISTERED | 404 | The token is usually no longer valid | Delete the token |
INVALID_ARGUMENT | 400 | A request value is invalid, which may be the payload or the token | Check the payload first. Delete the token only if the payload is completely valid |
SENDER_ID_MISMATCH | 403 | The token belongs to a different sender | Send from the Firebase project the app registered with |
THIRD_PARTY_AUTH_ERROR | 401 | The APNs certificate or web push key is invalid or missing | Check your credentials. Don't delete tokens |
QUOTA_EXCEEDED | 429 | A sending limit was exceeded | Slow down and retry with backoff |
UNAVAILABLE, INTERNAL | 503, 500 | A temporary problem at FCM | Retry with backoff and check the FCM status dashboard |
You can build a valid test message with the free FCM payload builder, which helps rule out the payload.
If almost every token fails at once
A few dead tokens are normal, because people uninstall apps. If most of your tokens suddenly fail, look for a shared cause before you delete anything:
- Did you change Firebase projects or service accounts recently?
- Did your code start altering tokens when it stores or reads them?
- Can you get a fresh token from a test device and send to it?
- Does the FCM status dashboard show a problem?
Pause any automatic cleanup while you check, so a bug on your side doesn't wipe good tokens. If a fresh token also fails and your setup looks right, contact Firebase support.
On notifySphere
The notifySphere React Native SDK re-registers a device when its FCM token changes, and logout() unsubscribes the device and deletes its token when someone signs out. For the iOS setup error that often comes before this one, see No APNS token specified before fetching FCM token.
Frequently asked questions
What does FCM UNREGISTERED mean?
It means the app instance is no longer registered with Firebase Cloud Messaging, so that token usually won't work again. Firebase's advice is to remove the token and stop sending to it. The app gets a new token the next time it registers.
Is registration-token-not-registered the same as UNREGISTERED?
Yes, for practical purposes. UNREGISTERED is the error code from the FCM HTTP v1 API, usually with a 404 and the message "Requested entity was not found." messaging/registration-token-not-registered is how the Firebase Admin SDK for Node.js reports it.
Should I retry a message that failed with UNREGISTERED?
No. Retrying won't bring the token back. Retry 429, 500 and 503 errors with backoff instead, and delete tokens that return UNREGISTERED.
Do FCM tokens expire?
On Android, Firebase treats a registration as expired after 270 days of inactivity. On iOS and other platforms it relies on the underlying push service, which doesn't have that limit, so Firebase recommends removing stale tokens yourself. Its default definition of stale is no connection to FCM for over a month.
Does UNREGISTERED mean the user uninstalled the app?
Often, but not always. It can also follow an app update, a token refresh, or your app deleting its token. Treat it as a dead token, not as proof of an uninstall, especially if you use it to measure uninstalls.