Firebase Cloud Messaging throws this error when too many notifications hit the same token or topic inside FCM’s per-target quota window. Spread the burst over five minutes or request a temporary quota bump before retrying.
Firebase Cloud Messaging enforces quotas to protect its infrastructure, and this error means FCM stopped processing once a registration token, topic, or condition received more traffic than the per-target window allows. The service groups sends into a five-minute burst limit, so you cannot push the same audience harder than that window without standing in line. The Firebase FAQ on FCM quotas spells this out: you must spread traffic over five minutes, scheduled events should start early, and quota increases are only granted with advance notice. When the limit is hit, FCM returns 429/QUOTA_EXCEEDED rather than retrying implicitly, so you need to throttle or wait for the quota window to reset before sending more messages.
Inspect the error metadata so you can confirm you hit the target quota and see the Retry-After hint before retrying:
try {
await messaging.send(message);
} catch (error) {
console.error('FCM error code:', error.code);
console.error('Message:', error.message);
console.error('Retry-After seconds:', error.errorInfo?.retryAfter);
}The error details highlight whether the limit is per token, topic, or condition and prevent accidental immediate retries that burn the same quota window.
Split your audience and add a short delay before sending to the next slice. A simple throttle loop that waits after each chunk keeps you inside the broadcast limit:
const chunkSize = 200;
const delayMs = 30_000; // 30 seconds per chunk
for (let i = 0; i < tokens.length; i += chunkSize) {
const batch = tokens.slice(i, i + chunkSize);
await Promise.all(batch.map(token => messaging.send({ token, notification })));
await new Promise(resolve => setTimeout(resolve, delayMs));
}Adjust the delay to spread the traffic so that any individual token or topic only sees one burst within five minutes.
Use the Firebase console quotas dashboard or Cloud Monitoring to see when you approach thresholds. In Cloud Monitoring you can filter for quota metrics such as serviceruntime.googleapis.com/quota/allocation/usage with the quota_metric label that corresponds to FCM. Create alerts for quota/exceeded errors so you know when sends are blocked before the event fires. The linked guide shows how to find quota_metric labels and build charts or alerting policies that surface usage spikes.
For one-time events that still need more throughput, file a quota request at least one month early with dates and audience size. Firebase explicitly honors such requests for events up to one month long but reverts the increase afterward. If you cannot get an increase, start sending 5+ minutes before the event and throttle the rest throughout the interval so you never hit the hard limit.
FCM treats each individual target (token, topic, condition) as its own quota bucket, so splitting a topic into multiple topic groups or regions can reduce the per-target pressure.
Quota windows reset automatically; hitting the error repeatedly points to sending logic that retries too aggressively or sits on stale registration tokens. Deduplicate sends per token and wait for the Retry-After before retrying.
Spark projects share the same per-target throttles as Blaze, so upgrading only helps if you also request a quota increase because quota assistance is limited by the plan and review process.
messaging/UNSPECIFIED_ERROR: No additional information available
How to fix "messaging/UNSPECIFIED_ERROR: No additional information available" in Firebase Cloud Messaging
App Check: reCAPTCHA Score Too Low
App Check reCAPTCHA Score Too Low
storage/invalid-url: Invalid URL format for Cloud Storage reference
How to fix invalid URL format in Firebase Cloud Storage
auth/missing-uid: User ID identifier required
How to fix "auth/missing-uid: User ID identifier required" in Firebase
auth/invalid-argument: Invalid parameter passed to method
How to fix "auth/invalid-argument: Invalid parameter passed to method" in Firebase