LEARN · DEBUGGING GUIDE

GCP Firestore Query Needs Index: Diagnosing and Fixing the Missing Index Error

The 'index required' error in Firestore means your query needs a composite index that doesn't exist yet. This guide shows you exactly how to find the missing index and create it, plus how to avoid hitting this in the future.

IntermediateDatabase7 min read

What this usually means

Firestore requires indexes on fields used in queries to ensure performance and consistency. For simple equality filters on a single field, automatic single-field indexes are created by default. However, any query that uses multiple fields (compound equality, range filters, or ordering on a different field) needs a custom composite index. When you get the 'index required' error, it means your query does not match any existing composite index. Firestore will return the error message with a direct link to create the needed index, but developers often miss this or ignore it, leading to production issues.

( 01 )Fast diagnosis

The first ten minutes — establish facts before touching code.

  • 1Look at the exact error message from the client SDK or REST API. It typically contains a URL with the index definition (e.g., /indexes?createIndex=...).
  • 2Open the Firebase Console > Firestore > Indexes tab. Check if the required composite index is listed as 'Creating' or missing entirely.
  • 3Run the query in the Firestore console's Query Editor. It will show a warning if an index is missing.
  • 4Check your Firestore database rules: missing indexes are not a permissions issue, but verify you are authenticated.
  • 5Use `gcloud firestore indexes composite list` to see all composite indexes in your project.
( 02 )Where to look

The specific files, logs, configs, and dashboards that usually own this bug.

  • searchFirebase Console > Firestore > Indexes tab (lists all composite indexes and their status).
  • searchClient logs: look for the full error object which includes the suggested index definition.
  • searchCloud Logging: filter for severity >= ERROR and search for 'index required' or 'FAILED_PRECONDITION'.
  • searchYour application's Firestore query code: examine the exact filters and orderBy clauses.
  • searchFirestore Emulator logs: if testing locally, the emulator may not enforce indexes but can hint.
  • searchFirestore REST API response headers (x-goog-*): sometimes include index recommendations.
  • searchTerraform or deployment scripts: check if composite indexes are defined in infrastructure-as-code.
( 03 )Common root causes

Practical causes, not theory. These are the things you will actually find.

  • warningNew query added to code without creating the corresponding composite index in Firestore.
  • warningIndexes created in Firestore console but not deployed to production environment (e.g., separate projects).
  • warningQuery uses a range filter (<, <=, >, >=) and orderBy on different fields without a matching composite index.
  • warningComposite index exists but order of fields in the query doesn't match the index order (equality fields first, then range, then order).
  • warningIndex was deleted or disabled accidentally (e.g., via Terraform state drift).
  • warningFirestore automatic index creation is disabled (by default it's enabled, but can be turned off).
( 04 )Fix patterns

Concrete fix directions. Pick the one that matches your root cause.

  • buildClick the link in the error message: it opens the Firebase Console with the index creation form pre-filled. Review and click 'Create'.
  • buildCreate the composite index via gcloud CLI: `gcloud firestore indexes composite create --collection-group=... --field-config=...`
  • buildFor Terraform users, define the index in `google_firestore_index` resource and apply.
  • buildEnsure the index covers all equality filters first, then the range filter, then the order field. For example, if query is `where('status', '==', 'active').where('created', '>', timestamp).orderBy('created')`, create index on `status ASC, created ASC`.
  • buildIf using emulator, sometimes you need to set FIRESTORE_EMULATOR_HOST and create indexes via the emulator's REST API.
  • buildConsider simplifying the query: if possible, use a single equality filter or denormalize data to avoid composite indexes.
( 05 )How to verify

A fix you cannot prove is a guess. Close the loop.

  • verifiedRun the query again in the Firebase Console Query Editor – it should return results without warnings.
  • verifiedExecute the query from your application and confirm no error is thrown.
  • verifiedCheck the Firestore Indexes tab: the new index should show status 'Ready'.
  • verifiedUse `gcloud firestore indexes composite list` and confirm the index appears.
  • verifiedWrite a unit test that runs the query against the emulator and expects success.
  • verifiedMonitor Cloud Logging for the error for 24 hours to ensure no recurrence.
( 06 )Mistakes to avoid

Things that make this bug worse or harder to find.

  • warningCreating an index that doesn't match the query's field order – Firestore is strict about order (equality fields first, then range, then orderBy).
  • warningForgetting to deploy indexes to all environments (dev, staging, prod) – use infrastructure-as-code to prevent drift.
  • warningAssuming the error is a permission issue – the error message is explicit; check indexes first.
  • warningIgnoring the error link – it's the fastest way to create the correct index.
  • warningCreating an index with the same fields but wrong direction (ASC vs DESC) when combined with orderBy.
  • warningDeleting old indexes that might be needed by other queries – always audit before removing.
( 07 )War story

Missing composite index causes production outage for user feed query

Backend EngineerNode.js 18, Firestore (Native mode), Firebase Admin SDK, Cloud Run

Timeline

  1. 09:15Deploy new feature: user feed query with where('active', '==', true).orderBy('createdAt', 'desc').limit(20)
  2. 09:20Cloud Run logs fill with 'FAILED_PRECONDITION: The query requires an index.' error for feed endpoint.
  3. 09:25PagerDuty alert triggered: 500 errors from feed endpoint, impacting all users.
  4. 09:30Check Firestore indexes – no composite index for (active, createdAt desc).
  5. 09:32Click the error link, review auto-generated index definition, click 'Create'.
  6. 09:35Index status shows 'Creating' – estimated 5 minutes to build.
  7. 09:40Feed endpoint still returning 500 – query still fails while index builds.
  8. 09:42Implement temporary workaround: remove orderBy, do client-side sorting.
  9. 09:45Deploy hotfix with orderBy removed.
  10. 09:48Feed endpoint works again (no order, less ideal but functional).
  11. 09:52Index becomes active. Redeploy original code with orderBy.
  12. 09:55All systems normal. Post-mortem: missing composite index in production due to manual creation only in dev.

We were rolling out a new feature: a paginated user feed sorted by creation date. I had tested locally with the Firestore emulator, which doesn't enforce composite indexes, so everything passed. I created the composite index in the dev console but forgot to replicate it in production.

The deploy went smoothly – no build errors. But within minutes, the feed endpoint was returning 500 errors. The logs showed the infamous 'index required' error. I initially thought it was a permission issue, but the error message was clear: missing composite index.

I clicked the provided link, which took me straight to the index creation form. I created the index, but it took about 5 minutes to build. During that time, the query still failed. I hotfixed by removing the orderBy clause and doing client-side sorting. Once the index was active, I redeployed the original code. The lesson: always ensure indexes are deployed to production via infrastructure-as-code, and be prepared for index creation time.

Root cause

Composite index on (active, createdAt desc) was missing in the production Firestore database.

The fix

Created the composite index via the Firebase Console link from the error message, then hotfixed the query temporarily to remove orderBy, and finally redeployed with the original query after index was built.

The lesson

Always manage Firestore indexes as code (Terraform or similar) to ensure consistency across environments. Also, the emulator does not enforce composite indexes, so test against a real Firestore instance or use the emulator's index management API.

( 08 )Understanding Firestore Index Requirements

Firestore uses indexes to make queries efficient. For every query, Firestore tries to find an index that matches the query's filter fields and sort order. Single-field queries (e.g., `where('status', '==', 'active')`) use automatic single-field indexes. However, when you have multiple `where` clauses or a `where` combined with an `orderBy` on a different field, Firestore needs a composite index that includes all those fields in the correct order.

The composite index must list equality fields first, then the range field (if any), then the orderBy field. For example, a query `where('status', '==', 'active').where('price', '>', 10).orderBy('price')` requires an index on `status ASC, price ASC`. The direction (ASC/DESC) matters for the orderBy field; for equality fields, direction is irrelevant because all values are equal.

( 10 )Avoiding Index Pitfalls in CI/CD

Treat indexes as part of your infrastructure. Use Terraform's `google_firestore_index` resource or Firebase CLI's `firebase firestore:indexes` to export and import index definitions. Store the `firestore.indexes.json` file in your repo and run `firebase deploy --only firestore:indexes` in your CI pipeline.

Common mistakes: defining indexes with the wrong field order (equality before range), forgetting to include all `where` fields, or mixing directions incorrectly. For range filters, the field must be in the index and its order must match the query's orderBy (if any). If the query does not have an orderBy, the range field's direction can be either ASC or DESC; Firestore can scan backwards.

( 11 )Handling Index Creation Timeouts

Creating a composite index is an asynchronous operation that can take a few minutes to several hours, depending on the size of the collection and the complexity of the index. During this time, queries that require the index will fail. Plan for this: create indexes before deploying dependent code, or use blue-green deployments where old code runs until indexes are ready.

If you need an immediate fix, consider removing the composite query from your code temporarily (e.g., by sorting client-side or using a different query pattern). Alternatively, you can use the Firestore REST API to create indexes and poll the status until 'READY'.

( 12 )Testing Indexes with the Firestore Emulator

The Firestore emulator does NOT enforce composite indexes by default. This leads to false confidence. To test index requirements locally, you can enable index enforcement in the emulator by setting the environment variable `FIRESTORE_EMULATOR_ENABLE_INDEX_ENFORCEMENT=true`. Alternatively, use the emulator's REST endpoint to create indexes programmatically.

Better yet, have a dedicated test Firestore project (or use the production project's indexes) and run integration tests against it. This catches missing indexes early.

Frequently asked questions

Why does my query work in the Firestore console but not in my app?

The Firestore console may be using a different project or the query might be simpler in the console. Ensure the console is connected to the same project and that the index exists. Also, check if the app is using a different collection path or field names.

Can I create an index for all possible queries?

No, you should only create indexes for queries you actually use. Each index consumes storage and incurs write costs. Firestore has a limit of 200 composite indexes per database (for Native mode). Plan indexes based on query patterns.

What if I need to query with multiple range filters on different fields?

Firestore does not support multiple range filters on different fields in a single query. You would need to restructure your data or perform filtering in your application code. Composite indexes cannot solve this; it's a fundamental limitation.

How do I delete an unused composite index?

In the Firebase Console, go to Firestore > Indexes, find the index, click the three-dot menu, and select 'Delete'. Or use gcloud: `gcloud firestore indexes composite delete INDEX_ID`. Be sure no queries depend on it.

The error says 'the query requires an index' but the link takes me to a 'create index' page with fields I don't recognize.

Double-check your query code. The link is generated based on the actual query sent to Firestore. Ensure you are not inadvertently adding extra fields or using different field paths. Review the `where` and `orderBy` clauses carefully.