Repairing the index registry
This guide shows you how to detect, audit, and repair a missing or corrupt index registry in an Exofind deployment, and how to use the registry audit to inspect storage drift. Use this guide when a node reports registry errors, when an index listing returns empty despite data existing in object storage, or when checking for unreferenced data in a bucket.
Prerequisites
Section titled “Prerequisites”Before you begin:
- Ensure that your deployment uses
objectstorage mode. Registry audit and repair endpoints are unavailable inlocalstorage mode. - Obtain an API key with the deployment-scoped
registry.auditandregistry.repairpermissions, or use the root key (EXOFIND_AUTH_ROOT_KEY). API keys generated from theadminrole before these permissions existed do not include them. - Ensure that no index rollouts are in flight before performing a repair.
Recognize a lost or corrupt registry
Section titled “Recognize a lost or corrupt registry”The deployment registry records which indexes exist, their available
generations, and which generation serves requests for the bare index name. In
object storage mode, it is stored at registry/indexes.ef.bin under the
configured storage prefix. In local storage mode, it is stored in
registry.ef.bin in EXOFIND_STORAGE_LOCAL_DIRECTORY, beside the index
directories in indexes/<index>@<generation>/.
A lost registry costs the whole deployment in local storage mode, where the
index directories are the only copy of the data, and only a re-pull in object
storage mode. Local storage mode has no audit or repair endpoint, so you put
registry.ef.bin back from a backup.
Identify registry problems by checking node logs, readiness checks, and index listings:
- Missing registry (
absent): A node that already read the registry keeps its copy and logs an error instead of serving an empty list:Such a node stays ready and continues serving its copy. A node that starts with a missing or empty registry keeps the index directories it holds instead of deleting them, and logs an error:The index registry is gone from the storage, but this node read it before. Keeping the copy this node holds. Restore the registry from a backup, or rebuild it with the registry repair endpoint if you store indexes in object storageRequests for unlisted indexes returnThe index registry lists no indexes, but this node has index directories on disk. A registry that was lost looks the same as a deployment with no indexes, so the node keeps the directories instead of deleting them. Requests for those indexes return not found until the registry lists them again. Restore the registry from a backup, or rebuild it with the registry repair endpoint if you store indexes in object storageindex:not_found, andGET /v1alpha1/admin/indexesdoes not list them until the registry lists them again. - Corrupt registry (
corrupt): A node that starts after the corruption stays running but never becomes ready:GET /q/health/readyreturns HTTP503with theindex-registrycheck markedDOWN. A node that read the registry before the corruption stays ready and keeps serving the copy it holds. Either way, the node log records the following message:The node continues to serve its in-memory copy of the registry, and admin API endpoints remain accessible. Authentication continues to function because API keys reside in a separateThe stored registry can not be parsed, using the copy this node holds. Repair it through the registry audit endpointkeysstorage object.
Audit the registry and storage
Section titled “Audit the registry and storage”Run an audit to compare the contents of the registry object against the data stored in your bucket. The audit endpoint is read-only and is handled directly by the receiving node without forwarding to an indexer.
- Query the registry audit endpoint:
GET /v1alpha1/admin/registry/audit
- Inspect the
registryfield in the response:present: The registry object exists and can be parsed.absent: No registry object exists in the storage bucket.corrupt: The registry object exists but its contents cannot be parsed.
- Review the
indexeslist in the response. Each index entry provides the following fields:name: The index name.registered:trueif the index is currently defined in the registry.live: The generation answering queries for the bare index name. This field is omitted if unregistered or if no live generation is set.proposedLive: The highest-numbered generation that a repair withpromoteNewestwould set as live.removedAt: Present when a delete marked the storage and the sweep has not removed it yet. Marked entries are unregistered, not proposed for promotion, and a repair skips them unless restored.generations: The generations found for the index.
- Review the
storedstate for each generation:synced: The bucket contains a completedmanifest.ef.binfile. Nodes can pull and serve this generation.incomplete: The bucket prefix exists without a manifest. This occurs when an initial push was interrupted or when storage remains from a swept generation.missing: The generation is registered in the registry, but no data exists in the bucket. Each generation also includesremovedAtwhen a delete marked the storage and the sweep has not removed it yet. Marked generations are unregistered, not proposed for promotion, and a repair skips them unless restored.
- Check the
unusablelist for prefixes in the bucket that do not match valid index or generation name formats.
Inspect storage drift on a healthy deployment
Section titled “Inspect storage drift on a healthy deployment”You can run the audit endpoint on a healthy deployment (registry: present) to
detect orphaned or unreferenced data:
- Unregistered
syncedgenerations: A deleted index now showsremovedAtand waits for the sweep. An unregistered generation withoutremovedAtis an interrupted rollout, or storage deleted before removal marks existed. To remove such leftover storage, register it with a repair and then delete it through the API, which marks it for the sweep. incompletegenerations: Leftover prefixes from aborted pushes or disk sweeps.missinggenerations: Registered generations whose storage data was removed from the bucket.
Because object storage cannot determine whether an unregistered generation is an interrupted rollout or leftover data from a deleted index, evaluate these entries before manually cleaning storage objects.
Repair the registry
Section titled “Repair the registry”A repair replaces a corrupt registry or creates an absent registry using
valid data found in the bucket. The repair only registers synced generations
that are not already present in the registry. It never deletes indexes,
generations, or bucket data. Existing registered indexes retain their settings,
features, and live generation assignments.
-
Verify that no rollout operations are currently running.
-
Send a repair request to the admin API.
To register all
syncedgenerations without setting live generations for newly created indexes:POST /v1alpha1/admin/registry/actions/repairTo register all
syncedgenerations and configure each newly created index to answer for its highest-numbered generation:POST /v1alpha1/admin/registry/actions/repairContent-Type: application/json{"promoteNewest": true}Note:
promoteNewestonly promotes generations with numeric names. Generations with non-numeric names are not promoted automatically.To restore marked storage during the repair, provide the
restorefield with a list of index or generation names:POST /v1alpha1/admin/registry/actions/repairContent-Type: application/json{"promoteNewest": true,"restore": ["books"]} -
Inspect the repair response:
{"createdIndexes": ["books"],"addedGenerations": ["books@1", "books@2"],"promoted": ["books@2"],"restored": ["books"]}The
restoredfield lists the names whose removal mark the repair removed. If all lists in the response are empty, the registry was already complete. -
If you did not use
promoteNewest, or if an index uses non-numeric generation names, manually promote the desired generation for each restored index:POST /v1alpha1/admin/indexes/products@1/actions/promote
Restore a deleted index or generation
Section titled “Restore a deleted index or generation”When an index or generation was deleted, you can restore it before the background sweep removes its storage from the bucket.
- Run the audit endpoint and find the entry with
removedAt:GET /v1alpha1/admin/registry/audit - Send a repair request with
restorenaming the index or generation, and setpromoteNewesttotrueif the index should answer for its highest-numbered generation:POST /v1alpha1/admin/registry/actions/repairContent-Type: application/json{"promoteNewest": true,"restore": ["books"]} - Promote another generation if needed:
POST /v1alpha1/admin/indexes/books@1/actions/promote
Note: Restoring works only while the mark stands, that is within
EXOFIND_INDEXES_REMOVAL_GRACE after the delete. The registry does not remember
which generation was live before the delete. The search settings apply again
once the index is registered.
Handle errors and unsupported findings
Section titled “Handle errors and unsupported findings”When auditing or repairing the registry, handle errors and unfixable findings as follows:
409 Conflictwithindex:registry:audit_unavailable: The node is running withEXOFIND_STORAGE_MODE=local. Local storage mode does not support audit or repair endpoints.409 Conflictwithstorage:io_error: Remote object storage is unreachable. Check network connectivity and storage credentials.409 Conflictwithstorage:conflict: A concurrent registry write occurred during the repair. Retry the request when other operations finish.missingfindings: The repair does not restore missing bucket data. Remove the generation from the registry or restore the missing objects from a storage backup.incompleteandunusablefindings: The repair ignores these prefixes. Anincompletegeneration carryingremovedAtis an interrupted removal that the next sweep pass finishes. Delete other unneeded leftover objects directly from your bucket.
Confirm the registry status
Section titled “Confirm the registry status”After running a repair, verify that the deployment is serving the repaired indexes:
- Check the node readiness endpoint:
Verify that the response returns HTTP statusGET /q/health/ready
200and theindex-registrycheck reports"status": "UP". - Run the audit endpoint to verify registry integrity:
Verify thatGET /v1alpha1/admin/registry/audit
"registry": "present"and all expected generations report"registered": true. - Query the index listing on the node that handled the repair:
Verify that all restored indexes are listed.GET /v1alpha1/admin/indexes
The node that executed the repair serves the updated registry immediately.
Other nodes pick up the updated registry during their next refresh pass, within
the duration configured by EXOFIND_INDEXES_REFRESH_INTERVAL (30 seconds by
default).
Related
Section titled “Related”- Admin API - Endpoints and payload structures for index management.
- Authentication - API key permissions, roles, and the root key.
- Operating a deployment - Monitoring node health, writer assignments, and storage operations.
- Rolling out a definition change - Creating and switching between index generations safely.
- Generations - How generation numbering, promotion, and immutable storage layouts work.
- Storage layout - The registry object, the removal marks, and every other object the audit reads.
Exofind is built by Level Four AB and is available under the Apache License 2.0.