Describe the bug
The App Catalog feature does not function in a default in-cluster deployment, despite being described as supported since v0.37.0.
In practice, two bugs in Headlamp core plus several undocumented deployment requirements prevent the feature from working out-of-the-box.
Expected behavior:
- Enabling
config.enableHelm: true should expose an "Apps" section in the UI
- Users should be able to browse catalogs (e.g. ArtifactHub) and perform Helm operations
Actual behavior:
- No "Apps" section appears
- No indication that App Catalog exists or is misconfigured
- No user-visible errors or warnings
This results in a silent failure where the feature appears to not exist.
To Reproduce
Case 1: Default in-cluster deployment (baseline failure)
- Deploy Headlamp via Helm:
helm install headlamp headlamp/headlamp --set config.enableHelm=true
- Access the UI
- Observe that no "Apps" section exists
- No errors or warnings are shown
Case 2: After manually enabling plugin (reveals core issues)
- Install
app-catalog plugin via initContainer or sidecar
- Create a catalog Service with expected labels/annotations
- Attempt to access catalog UI
- Observe:
- Routes may return 404 ("Not Found")
- Helm operations fail silently (backend uses
system:anonymous)
- No actionable UI errors
Environment:
- Installation type: Helm (in-cluster)
- Headlamp Version: chart 0.28.1 / app v0.26.0 (also reproduced on
main)
- Auth: token-based (non-OIDC, default in-cluster)
- Cluster: Kind v0.27.0 (reproduces on other clusters as well)
Are you able to fix this issue?
Yes (I will propose a PR; it's 2-3 files <4-5 LOC change)
Additional Context
Summary of failure modes
The issue is not a single failure but a combination of seven independent failure modes. Hitting any subset results in a non-functional App Catalog with no user-visible signal.
- Code bug 1:
helmRouteReleaseHandler conditionally skips setTokenFromCookie() in non-OIDC setups → Helm operations run as system:anonymous
- Code bug 2: React key collision in
RouteSwitcher → dynamically registered plugin routes do not mount
- Deployment gap:
app-catalog plugin not included in container image
- Deployment gap: missing default
--proxy-urls (ArtifactHub unreachable)
- Deployment gap: no catalog Service template → plugin discovers nothing
- Deployment gap: undocumented
catalog.headlamp.dev/protocol annotation
- Deployment gap: ExternalName Services incompatible with service proxy (TLS/SNI issues)
Result: No user-visible errors or actionable feedback in the default case.
Code Bug 1 — Helm auth guard
helmRouteReleaseHandler conditionally calls setTokenFromCookie():
if (c.UseInCluster || c.OidcUseCookie) && context.OidcConf != nil {
setTokenFromCookie(r, clusterName)
}
In non-OIDC deployments, this prevents the Authorization header from being set.
Observation:
helmRouteRepositoryHandler calls this function unconditionally and works correctly.
Proposed fix:
setTokenFromCookie(r, clusterName)
Safe because the function is a no-op when no cookie is present.
Code Bug 2 — React key collision
All routes use the same key:
This prevents React from mounting dynamically registered routes.
Proposed fix:
key={`${route.path}-${getCluster()}`}
Deployment gaps (recommendations)
These are differences between desktop and in-cluster behavior:
- Container image does not include
app-catalog plugin
- Helm chart does not configure
--proxy-urls
- No catalog Service template or documentation
- Required annotations are undocumented
- ExternalName Services do not work with service proxy
These likely require alignment on packaging/documentation direction rather than code fixes, and likely be outside the scope of the initial (proposed) fix to this bug.
PR scope
I plan to submit a minimal PR addressing the two code issues only:
- Remove OIDC guard in
helmRouteReleaseHandler
- Fix React key collision in
RouteSwitcher
Happy to discuss approach for deployment-related gaps separately (docs, Helm chart, or packaging changes).
Describe the bug
The App Catalog feature does not function in a default in-cluster deployment, despite being described as supported since v0.37.0.
In practice, two bugs in Headlamp core plus several undocumented deployment requirements prevent the feature from working out-of-the-box.
Expected behavior:
config.enableHelm: trueshould expose an "Apps" section in the UIActual behavior:
This results in a silent failure where the feature appears to not exist.
To Reproduce
Case 1: Default in-cluster deployment (baseline failure)
Case 2: After manually enabling plugin (reveals core issues)
app-catalogplugin via initContainer or sidecarsystem:anonymous)Environment:
main)Are you able to fix this issue?
Yes (I will propose a PR; it's 2-3 files <4-5 LOC change)
Additional Context
Summary of failure modes
The issue is not a single failure but a combination of seven independent failure modes. Hitting any subset results in a non-functional App Catalog with no user-visible signal.
helmRouteReleaseHandlerconditionally skipssetTokenFromCookie()in non-OIDC setups → Helm operations run assystem:anonymousRouteSwitcher→ dynamically registered plugin routes do not mountapp-catalogplugin not included in container image--proxy-urls(ArtifactHub unreachable)catalog.headlamp.dev/protocolannotationResult: No user-visible errors or actionable feedback in the default case.
Code Bug 1 — Helm auth guard
helmRouteReleaseHandlerconditionally callssetTokenFromCookie():In non-OIDC deployments, this prevents the Authorization header from being set.
Observation:
helmRouteRepositoryHandlercalls this function unconditionally and works correctly.Proposed fix:
Safe because the function is a no-op when no cookie is present.
Code Bug 2 — React key collision
All routes use the same key:
This prevents React from mounting dynamically registered routes.
Proposed fix:
Deployment gaps (recommendations)
These are differences between desktop and in-cluster behavior:
app-catalogplugin--proxy-urlsThese likely require alignment on packaging/documentation direction rather than code fixes, and likely be outside the scope of the initial (proposed) fix to this bug.
PR scope
I plan to submit a minimal PR addressing the two code issues only:
helmRouteReleaseHandlerRouteSwitcherHappy to discuss approach for deployment-related gaps separately (docs, Helm chart, or packaging changes).