Area: Product Issues
Sub-Area: Domain Hierarchy / Search Failures
Issue
When a DataHub domain is configured with itself as its own parent (a self-referential loop such as urn:li:domain:example pointing to urn:li:domain:example as its parentDomain), the entire domain hierarchy becomes unresolvable. Because DataHub reads the domain hierarchy as a whole, this single bad reference propagates outward and causes cascading failures across all domain-related queries — breaking wildcard search, browse-path navigation, and homepage modules — even for domains that have no relationship to the self-referencing one. This behavior was not enforced in DataHub versions prior to approximately 2.3.x, so environments that upgrade from an older version may encounter this failure for the first time post-upgrade, even though the bad data predates the upgrade.
Error Messages
{"message": "loops not allowed", "extensions": {"code": 400, "type": "BAD_REQUEST", "classification": "DataFetchingException"}}-
Something went wrong(generic UI error screen on search or homepage)
You Might Be Asking
- Why did search break site-wide after upgrading DataHub, even though the problem domain has nothing to do with the assets I was searching for?
- Can a domain loop involving two or more nodes (A → B → A, or A → B → C → A) cause the same crash?
- My ingestion source says the domain's parent is valid — does DataHub support self-referencing domain parents?
- Will this issue persist after every ingestion run if I only fix the domain in the UI?
Solution
-
Confirm the root cause using the browser network console.
Open your browser's developer tools, reproduce the failed search or homepage load, and inspect the GraphQL responses. Look for a response body containing
"loops not allowed"along with a path that traversesdomain → parentDomains. This confirms a self-referencing domain is the cause.{ "errors": [ { "message": "loops not allowed", "path": [ "search", "...", "entity", "domain", "domain", "parentDomains" ], "extensions": { "code": 400, "type": "BAD_REQUEST", "classification": "DataFetchingException" } } ] } -
Identify the self-referencing domain.
Use the DataHub GraphQL API to query domain properties and inspect the
parentDomainsfield. A domain is self-referencing when its own URN appears as an entry in its ownparentDomainslist.query { domain(urn: "urn:li:domain:<your-domain-id>") { urn properties { name } parentDomains { domains { urn } } } } -
Remove the self-reference via the DataHub UI.
Navigate to Govern → Domains, open the offending domain, and edit its properties to remove the parent domain assignment. A top-level domain should have no parent set. Save the change. Search and homepage modules should recover immediately without any reindex or restart.
-
Alternatively, remove the self-reference via the DataHub REST API.
If UI access is unavailable, emit an updated
DomainPropertiesaspect with noparentDomainfield set:curl -X POST \ "https://<your-instance>.acryl.io/api/v2/entity/domain/urn%3Ali%3Adomain%3A<your-domain-id>/domainProperties" \ -H "Authorization: Bearer <your-token>" \ -H "Content-Type: application/json" \ -d '{ "value": { "com.linkedin.domain.DomainProperties": { "name": "<your-domain-name>", "description": "<your-domain-description>" } } }'Note the absence of a
parentDomainkey — omitting it removes the existing parent assignment. -
Fix the ingestion source to prevent the self-reference from being re-introduced.
If an ingestion recipe or custom transformer is responsible for assigning domain parents, it must be updated to skip or nullify the parent assignment when the resolved parent URN equals the domain's own URN. Failing to do this means every ingestion run will re-apply the bad data and break search again. Example guard logic in a Python-based custom source or transformer:
def get_parent_domain(domain_urn: str, resolved_parent_urn: str) -> str | None: """ Returns the parent domain URN, or None if it would create a self-reference. A top-level domain should have no parent. """ if resolved_parent_urn == domain_urn: # Self-reference detected — treat this domain as top-level return None return resolved_parent_urnIf you use a DataHub-provided transformer in your recipe YAML, add a conditional filter or post-processing step to drop
parentDomainwhen it equals the domain's own URN before the metadata is emitted. - Temporarily pause the offending ingestion source if the transformer fix cannot be deployed immediately. Re-running the ingestion without the fix will restore the self-reference and break search again.
-
Verify recovery.
After editing the domain and before re-enabling ingestion, confirm that a wildcard search (
*) returns results and that the homepage domain modules render correctly.
Additional Notes
-
Scope of the failure: Only a direct self-reference (A → A) causes this crash. Multi-node cycles such as A → B → A or A → B → C → A do not produce the
loops not allowederror, though they will prevent affected domains from appearing at the top level of the Domains UI because none of them has an empty parent. -
Version behavior:
- Prior to ~2.3.x: Self-referencing domain parents were silently accepted and did not break search.
- 2.3.x: The loop check is enforced at query time. A self-referencing domain will cause site-wide search and homepage failures.
- 2.4.0 and later: DataHub prevents a domain from being saved with itself as a parent. If an ingestion source still sends a self-reference, DataHub will silently skip the parent assignment and the ingestion run will still report as successful — making the problem easy to miss. It is still strongly recommended to fix the ingestion source regardless of version.
- Silent ingestion failure on 2.4.0+: Because the ingestion run reports success even when the self-referencing parent is dropped, teams that do not fix their transformer may not notice that domain name or description updates are being silently ignored.
-
No reindex required: Removing the self-referencing parent via the UI or API immediately resolves search failures. A
restoreIndicesoperation is not needed for this specific issue.
Related Documentation
- DataHub Domains Overview
- DataHub Entity API Reference
- Metadata Ingestion Transformers
- Restore Indices (restoreIndices)
Tags: domain, self-reference, loops not allowed, search broken, homepage modules, domain hierarchy, ingestion transformer, upgrade regression, parentDomain, DataFetchingException