Why orphaned entities appear in the Backstage catalog and when you need a policy
Orphaned entities appear in the Backstage catalog whenever the source that created them changes and the catalog is not told. A repository is renamed, archived or deleted, a discovery provider stops matching a path, or an import file is removed from a Git location, yet the entity it produced remains in the catalog with its last known owner, lifecycle and links. An orphan is an entity that no longer has a source backing it. The catalog is a reflection of its sources, not a separate record of truth, so it stays accurate only when the sources it reads are the ones your organization still maintains. Until you decide what should happen to those leftovers, the catalog keeps presenting retired services as live ones.
The risk falls on owners and on anyone who uses the catalog to answer questions. A team that receives alerts, TechDocs links or scorecard results for a repository nobody works in will spend time on work that does not exist. Auditors who use the catalog as an asset inventory will count systems that were decommissioned. Before you connect large sources such as all GitHub, GitLab or Bitbucket repositories in your organization, decide how the catalog should treat an entity whose source disappears, and who is responsible for confirming that a deletion is intended. Confirm this behavior for the provider types you plan to use, since handling differs between static locations and discovery providers.
The policy needs three decisions: whether a missing entity is removed or kept, how an entity that a team wants to keep is marked so the catalog does not treat it as stale, and what happens when a whole provider is removed from configuration. Each of these is a configuration choice with consequences for ownership data and for the plugins that depend on the entity. Write the decision down with the platform team and the owners who will be asked to act on orphan reports. Confirm the current default delete and keep behavior and the names of the relevant settings against the Backstage documentation for your installed release, because these areas change between versions.
Choosing the default delete strategy or keeping orphans
Platform teams usually want the catalog to show only what is currently maintained. With the delete strategy, an entity that ingestion no longer finds is removed once its source stops reporting it, so the catalog, its search results and its dashboards stay close to the live estate. This suits a portal where most entities come from repositories or discovery sources that change often, and where stale cards send teams to the wrong owner.
- Lower triage load: Removed repositories disappear without a manual cleanup ticket.
- Accurate search: Stale components do not appear in search results or template pickers.
- Current ownership views: Owner lists reflect the catalog as it exists today, not historical records.
- Broader removal risk: A failed source call, a changed path or a renamed organization can remove entities that are still maintained, so watch removal volume after every configuration change.
Confirm how your ingestion behaves when a source request fails, and whether a partial result could be mistaken for a removal.
Some assets run for years without a repository that the catalog scans, such as a batch job, a vendor appliance, a legacy database or a shared service owned by a team that does not manage code in Git. For these, the keep strategy avoids losing the record when a scan misses them. Marking the entity as an orphan keeps its ownership, annotations and documentation visible while the owning team is located.
- Continuity: The entity, its annotations and any linked documentation stay available during the review.
- Visible risk: Orphan status can be listed and reviewed, so unscanned assets are not silently dropped.
- Manual upkeep: Someone must decide the fate of each orphan, which adds recurring review work.
- Growing noise: Unowned entities accumulate unless a review cycle closes them or reassigns them.
Check whether your portal views show the orphan marker, who reviews the orphan list, and how often that review happens.
Organizations that answer audit questions about past ownership need records showing who owned a system and when that ownership ended. A deleted entity leaves only what the catalog history or your own logs retain, so retention matters as much as the strategy itself. The keep strategy preserves the entity object for the period you define, which makes an ownership trail easier to reconstruct. The catalog is not an audit system, though. It records what the catalog saw, and auditors will test the retention and change records your organization can actually produce.
- Last known owner: The owner and annotations remain attached to the orphaned record.
- Export before deletion: Snapshot entries into your own record store if you need longer retention than the catalog provides.
- Retention rules: Define how long orphaned records are kept and who may remove them.
- Scope of claims: A catalog record shows what was recorded, not proof that a control operated.
Confirm with your compliance lead which retention period and record format your auditors expect before you choose keep for regulated systems.
Each strategy changes what plugins and search display. Plugins that read entity lists pick up whatever the catalog holds, so a kept orphan can appear in counts and views, while a deleted entity drops out of them. Search follows the catalog, so kept orphans stay findable unless your filters exclude them. Plugins that store their own data can behave differently, because their records are not always removed when the catalog entity is.
- Plugin-owned state: Plugins with their own stored data may keep state for entities that no longer exist, so check each plugin's cleanup behavior.
- Search results: Orphans may appear in search and template pickers unless filters exclude them.
- Ownership reports: Counts of unowned or stale entities grow under keep and shrink under delete, so every report needs a written definition.
- Linked entities: Systems, components and resources related to an orphan keep their relations, which can make the graph look more complete than it is.
Test the strategy in a staging portal, covering each plugin you run, and check its behavior after an entity is orphaned and after it is deleted.
Before you set a strategy, confirm the exact keys in the catalog configuration reference for your Backstage version, because key names and defaults can change between releases. Test each setting against a non-production source you can safely break, verify the result, and only then apply it to production sources. Store the chosen values under version control so changes are reviewed like other configuration.
- Global orphan strategy: Confirm the key that sets delete or keep for entities by default, and its default value.
- Provider removal behavior: Confirm the option for entities from removed providers (orphanProviderStrategy) and whether it can be set per provider.
- Orphan annotation: Confirm that orphaned entities carry the backstage.io/orphan annotation and that your views and filters read it.
- Upgrade effects: Read the release notes for each upgrade, since defaults and behavior can change.
Assign an owner to review orphan volume after each configuration change and after each upgrade.
Orphan and provider strategy options compared
This table compares the choices for catalog entities that lose their source, from default orphan deletion to provider removal settings. Read each row against the source you are retiring or migrating. The main takeaway is that the chosen strategy decides whether an entity is removed, lingers, or returns on the next refresh, so confirm each key before you change it.
| Option | When it fits | Trade-off | Config key to verify |
|---|---|---|---|
| Default orphan deletion | Catalog should mirror the source exactly and stale entries are unwanted | Entities can be removed if a source is briefly unreadable or misconfigured | Default orphan strategy in catalog config |
| Keep orphans | Migrations or reviews where owners must confirm before removal | Stale entities stay in search, ownership views and the catalog graph | Keep value of the orphan strategy setting |
| Orphan annotation review | Teams want a visible list of candidates before any deletion | The annotation marks entities but does not remove them on its own | Orphan annotation name in the current docs |
| Delete on provider removal | A retired source should take its entities with it | Removing one provider config can delete many entities at once | orphanProviderStrategy set to delete |
| Keep on provider removal | Sources are decommissioned gradually and entities must outlive them | Entities persist with no live source of truth and need manual cleanup | orphanProviderStrategy set to keep |
| Per-provider deletion settings | Different sources need different deletion rules in one catalog | More configuration to review and keep consistent during upgrades | Provider-level keys under catalog providers |
| Manual unregister of a location | One-off removal of an entity that no source should still manage | If the source still lists the entity, it returns on the next refresh | Location registration and the source file that declares it |
Why deleting a still-maintained entity does not stick
A manual delete in the catalog is undone at the next refresh if the source still describes the entity. The catalog treats the descriptor file or the provider's output as the record of truth. When a location or entity provider returns the entity again, the processing loop recreates it, so removing it from the catalog UI or API only creates a short gap. Teams that see an entity reappear after deleting it are usually not facing a bug. The source still says the entity exists, and the catalog is doing what it was built to do.
The durable fix is to change the source. For a descriptor in a repository, remove the catalog-info.yaml file or the entry that points to it, or change the entity so it no longer declares itself. For a discovery provider, such as a Git provider scanning organization repositories, the repository must be archived, renamed, moved out of the matched path, or otherwise excluded from the discovery rules. For a custom provider, the record must disappear from the upstream inventory. Confirm which of these applies by checking the location or provider configuration in your own deployment before you change anything, because each path has different ownership and different side effects on other entities.
The owner of the source must make that change, not the platform team operating the portal. A platform admin can often delete the entity in the catalog, but the next run will restore it, which wastes time and leaves the team that maintains the repository unaware of the mismatch. Agree on a clear contact for each provider, record who is accountable for removing stale descriptors, and confirm the expected path with the owning team before a bulk cleanup. Hypothetical example: a service whose repository was archived but still matches a discovery pattern will keep returning until the pattern or the repository status is changed.
Setting up a cleanup policy for orphaned entities
This sequence sets a deliberate cleanup policy for the catalog, so entities whose source has disappeared are removed or kept on purpose, not by default. It ends with a tested removal in a staging catalog and a confirmed view of the orphan marker and deletion in both the UI and the API.
Inventory every provider and location
Platform engineers list each catalog provider, static location and discovery source defined in the app configuration. For each one, they record the system of record it reads from, the team that owns that system, and the kinds of entities it produces. Include sources added to the configuration by hand in the past, since those are the most likely to be forgotten. The check: the inventory accounts for every source in the loaded configuration of the running backend, and every source has a named owner.
Decide the strategy for each provider
The platform team and the owner of each source agree whether entities from that source should be deleted when the source is removed or kept for review. Authoritative sources, such as an internal service inventory, usually need a different answer from a short-lived test repository. Record each decision beside its inventory row, along with the approver. The check: every row has one agreed answer and an approver, so no source is left on a default that nobody chose.
Set orphan handling in configuration
Platform engineers set the catalog-wide orphan strategy in the app configuration, choosing delete or keep as the baseline. They then set the provider removal behavior with the orphanProviderStrategy key for any provider that may be taken out of configuration. Confirm the exact key names and accepted values in the catalog documentation for your Backstage release before committing the change. The check: a staging deployment starts without configuration errors, and the loaded configuration shows the intended values.
Protect entities that must survive removal
Owners review entities that should persist even if their current source is retired, such as shared platform services or compliance-relevant components. For each one, they either point the entity at a source that will stay in place, move it to a provider that remains configured, or document it as a named exception. Explain to the owners that deleting a still-maintained entity in the UI does not stick: the next ingestion from its live source recreates it, so the durable fix is in the source. The check: every exception points to a source that still exists and appears in the inventory.
Remove a non-critical source in staging
In a staging catalog only, a platform engineer removes one non-critical location or provider that produces a small, known set of entities. They restart the backend or wait for the next scheduled ingestion cycle, then capture the processing logs for the affected source. Choose a source whose entities the team can recognize quickly. The check: the logs show the removal was processed, and no entities outside the removed source changed.
Verify orphan marking and deletion
Confirm the outcome in the Backstage UI and through the catalog API. In the UI, find the affected entities and check for the orphan annotation, backstage.io/orphan, or confirm they were removed, depending on the strategy chosen in the second step. Through the API, query the same entities and compare the metadata. Then restore the source and confirm the entities return without duplicates. The check: the UI, the API and the strategy record agree, and the restore test completes cleanly before any production change is scheduled.
Security and operational risks of cleaning up the catalog
Removing orphaned and stale entities changes who owns what, what auditors can trace, and who can reach the catalog's data. The cards below cover the risks that appear when cleanup runs without guardrails, and the checks to put in place before and after a removal.
Deleting ownership for live services
An entity removed because its source went quiet can take its spec.owner reference with it, leaving a running service with no owner in the portal. Teams then lose TechDocs links, alerts routing and template history for that component. Before cleanup, check which orphaned entities still have active deployments, and confirm the owning team with the people who run the service rather than trusting the catalog record alone.
Audit trail gaps after removal
When an entity disappears from the catalog, the portal no longer shows who registered it, when it was last processed, or what it pointed to. Auditors testing asset inventory and change management need that history. Confirm where your organization records catalog changes outside Backstage, such as Git history for descriptor files or logs from the backend, and retain them for the period your evidence requirements set.
Scope of delete permissions
Any identity allowed to remove entities can clear large parts of the catalog in one action, including entities owned by other teams. Review which groups hold catalog deletion rights through the permission framework, and separate the ability to unregister a location from the ability to delete an entity. Keep sign-in resolvers mapping each provider to one identity so a single compromised account does not carry broad delete rights.
Stale entities keeping old access hints
Entities that linger after a service is retired can still show API documentation, dependency graphs and annotations that point to decommissioned hosts, dashboards or credentials references. Engineers may act on those hints during an incident. Review stale entities for annotations that reference live infrastructure, and remove or update those references as part of the same cleanup change instead of leaving them behind.
Backups before bulk cleanup
A bulk removal is hard to reverse once processing has run, and the catalog state lives in PostgreSQL in production. Take a database backup and export the descriptor files from Git before any large cleanup, and test that you can restore the backup in a non-production environment. Record the backup identifier in the change ticket so the rollback point is known before deletion starts.
Monitoring for removal spikes
A provider that fails to return its full source list can mark most of its entities as missing, and the next run can remove them in one pass. Watch the number of entities removed per processing cycle and alert when it exceeds the normal range for that provider. Pause cleanup automatically when a spike appears, and confirm the source system is healthy before letting deletion proceed.
Questions teams ask before cleaning up orphaned entities
How much effort does a cleanup policy take, and what drives it?
Most of the effort is in deciding policy and checking the data, not in editing YAML. The main drivers are how many entities have no live source, how many of them have a clear owner, and how many plugins, dashboards or reports depend on entity names that a cleanup could remove. A catalog fed mostly by a few repositories is quick to review. A catalog fed by several discovery providers, with years of registrations, takes longer because each source has its own deletion behavior. Ask any partner to break the work into policy design, a dry run against your real catalog, owner review, and rollout, and to price each step separately in the written scope.
Can our team clean up orphaned entities without outside help?
Yes, if one or two engineers already run the Backstage backend and understand how providers and locations register entities. The work needs a working knowledge of catalog configuration, the orphan annotation, and the difference between the default delete strategy and keep. Teams often struggle with the coordination part: getting owners to confirm which entities are still in use, and agreeing on who makes the final call. An outside partner can help with the policy and the review, but the owners and the platform team must still make the decisions for their own services.
What does the cleanup need from entity owners?
Owners need to confirm whether each flagged entity is still maintained, retired, or waiting for a replacement. Without that answer, the platform team can only guess from the source repository and last activity. Ask owners to review a list grouped by team, not one entity at a time, and give them a clear deadline and a default action if they do not respond. Entities that are still maintained should be fixed at the source, because a deletion made in the catalog alone will not stick if the descriptor still exists in a source the catalog reads.
How long does rollout take, and what drives the duration?
Duration depends on the number of owners to contact, the number of providers involved, and how many entities each owner must review. A single provider with a small inventory can move through a cycle quickly. Multiple discovery sources, unclear ownership, and entities referenced by templates or dashboards add time. Confirm with your partner or internal team how many review rounds are planned, whether the rollout starts with a non-production catalog, and how deletions will be monitored after the first run.
Does removing a provider delete the entities it created?
Not automatically in every setup. The behavior is controlled by orphanProviderStrategy in the catalog configuration, which decides what happens to entities whose provider was removed from the configuration. Choosing the strategy is a policy decision: keeping entities preserves history but can leave stale records visible, while deleting them clears the catalog but can remove entities that teams still rely on. Test the setting in a non-production environment before changing it in production, and confirm the exact behavior for your Backstage version in the official catalog documentation.
Why does a deleted entity come back, and how do we prevent it?
An entity usually returns because a source still describes it. If a descriptor file remains in a repository that a location or discovery provider reads, the next refresh will register it again. Before deleting, find every source that produces the entity, including static locations and provider configuration. Then remove or change the source, or exclude the path, so the entity does not reappear. Deleting in the UI only changes the current state, and the catalog will process the source again on its schedule.
How should we handle entities whose owners have left?
Start by finding the owning group or user recorded in spec.owner and checking whether that identity still exists in your directory. Entities with no active owner should go to a named interim owner, usually a platform or governance group, who decides whether to transfer, retire, or delete them. Do not delete entities only because the owner left, since many services still run in production. Record the decision, so auditors and future reviewers can see who approved each change.
How DeployOpen scopes catalog cleanup work
Cleanup of orphaned and stale entities is usually a fixed-scope piece of work, and the written scope is where most of the decisions get made. DeployOpen agrees the scope in writing before work starts, and for this topic that scope names each entity provider and location in play, the strategy chosen for each source (including how orphanProviderStrategy behaves when a provider is removed), the catalog.orphanStrategy setting and any entity-level handling of the backstage.io/orphan annotation, and which teams own the entities that will be affected. A reader should expect the scope to list which sources are being retired, which are staying, and who signs off on deletions that will remove entities from the portal.
Testing is scoped separately from production. The written scope should state that changes are first applied to a non-production catalog that mirrors the real providers closely enough to show what would be deleted, kept or re-registered on the next refresh. Ask for a dry run that lists the entities each setting would affect, and confirm how the non-production catalog is seeded, whether it reads from the same Git organizations or from a copy, and how long a full refresh takes there. Handover documentation should cover the final configuration, the reasoning behind each strategy decision, the checks the portal team should run after a source is removed, and the procedure for recovering an entity that was deleted by mistake.
Quotes follow from the written scope, so the scope is what the reader compares across vendors or against their own team's estimate. DeployOpen does not publish a price list. Ask for a quote that separates the initial cleanup from any recurring work, such as reviewing new orphan reports after a source changes or re-running the catalog review after a Backstage upgrade. Ongoing support, upgrades and continuous testing are available as a retainer, which suits organizations whose sources change often enough that orphan handling needs regular attention rather than a single project.

