Backstage catalog "Placeholder ... could not be resolved" in CI
catalog-info.yaml can embed external content with $text, $json, or $yaml placeholders. The placeholder processor fetches the referenced URL, and if it cannot read or parse it, entity processing fails with "Placeholder ... could not be resolved".
What this error means
A catalog check or entity processing step reports "Placeholder $text could not be resolved, ..." naming the failing URL or a read/parse error.
Placeholder $text could not be resolved, Error: Could not read
https://github.com/acme/repo/blob/main/README.md, NotFoundError: Not Found {"status":404}Common causes
The referenced URL is wrong or private
The $text/$json/$yaml target 404s or requires auth the processor does not have, so the placeholder cannot be filled.
The target is not valid JSON or YAML
A $json or $yaml placeholder points at content that does not parse, so resolution fails even though the URL reads.
How to fix it
Point the placeholder at a readable raw URL
- Use a raw content URL the integration can read, not a rendered page.
- Ensure the integration token can access the target for private repos.
- Validate that $json/$yaml targets actually parse.
metadata:
annotations:
example: $text: https://github.com/acme/repo/blob/main/README.mdProvide integration credentials for private targets
Set the integration token so the placeholder processor can read private URLs during catalog processing.
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}How to prevent it
- Reference raw, readable URLs in placeholders.
- Ensure integration tokens can reach any private placeholder targets.
- Validate $json/$yaml targets parse before committing.