Chart: jfrog/xray (stable/xray)
Chart versions affected: 103.143.27 → 103.143.30, and current master (the relevant helper is identical across all of them)
Type: Bug
Summary
Enabling the SBOM microservice via sbom.enabled: true correctly renders the xray-sbom container into the Xray StatefulSet, and the service registers with the router at startup. However, the router's required-service-types list — JF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES, produced by the xray.router.requiredServiceTypes helper — is a hardcoded literal that does not include jfxsbm, regardless of sbom.enabled.
As a result the router logs a warning at registration and, on a router-only restart, silently drops the sbom service from its topology and does not re-register it (it only recovers on a full pod roll). There is no supported values-level way to fix this.
Steps to reproduce
helm template xray jfrog/xray --set sbom.enabled=true \
| grep -E 'name: xray-sbom|JF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES' -A1
Observed output:
- name: xray-sbom # <-- container IS deployed
...
- name: JF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES
value: jfxr,jfxana,jfxidx,jfxpst,jfxpe,jfob # <-- jfxsbm missing
Expected behavior
When sbom.enabled: true, the sbom service type (jfxsbm) should be included in JF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES (as it is a first-class service in the pod), so the router treats it as a required, restart-durable service — consistent with how the container itself is gated on sbom.enabled.
Actual behavior
jfxsbm is absent from the required set. At runtime the router logs (single-pod, splitXraytoSeparateDeployments.fullSplit=false):
[jfrou] [WARN ] [service_registry.go:78] - jfxsbm@<id> registered while it is not required
([jfxr jfxana jfxidx jfxpst jfxpe jfob]), this service will not be available
in case of router restart
And it is accurate. Restarting only the router container (the other containers, including xray-sbom, keep running):
[jfrou] external_topology ... xray-0 removed (jfxsbm@<id>),
state changed (jfob HEALTHY, jfxana HEALTHY, jfxidx HEALTHY, jfxpe HEALTHY, jfxpst HEALTHY, jfxr HEALTHY)
jfxsbm is removed from the topology and never re-registers on its own (verified over several minutes). The router then returns 404 for requests routed to the sbom service. Only a full pod restart re-registers it. (Async SBOM work off RabbitMQ continues; it is the router-fronted routing that is lost.)
Root cause
stable/xray/templates/_helpers.tpl:
{{- define "xray.router.requiredServiceTypes" -}}
{{- $requiredTypes := "jfxr,jfxana,jfxidx,jfxpst,jfxpe,jfob" -}}
{{- $requiredTypes -}}
{{- end -}}
The helper receives the root context (.) from the StatefulSet ({{ include "xray.router.requiredServiceTypes" . }}) but ignores it and emits a constant. It never consults .Values.sbom.enabled, so enabling sbom cannot influence the router's required-types string. (The xray.router.ipa.requiredServiceTypes variant has the same shape.)
Suggested fix
Make the helper conditionally append jfxsbm when the sbom service is enabled — mirroring the {{- if .Values.sbom.enabled }} gate already used for the container in xray-statefulset.yaml:
{{- define "xray.router.requiredServiceTypes" -}}
{{- $requiredTypes := "jfxr,jfxana,jfxidx,jfxpst,jfxpe,jfob" -}}
{{- if .Values.sbom.enabled -}}
{{- $requiredTypes = printf "%s,jfxsbm" $requiredTypes -}}
{{- end -}}
{{- $requiredTypes -}}
{{- end -}}
(If other optionally-enabled service types exist, the same pattern applies — the required-types list should be derived from the set of enabled services rather than a fixed literal.)
Workarounds attempted (and why they don't work)
- Override via
router.extraEnvVars (re-declaring JF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES): the chart appends extraEnvVars after its own entry, producing a duplicate env key. helm upgrade (server-side apply) rejects it:
failed to create typed patch object ... .spec.template.spec.containers[name="router"].env: duplicate entries for key [name="JF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES"]
- An "optional service types" router setting: none exists. The router's own startup config dump lists only
requiredServiceTypes (no optionalServiceTypes).
So there is no clean way for a chart consumer to correct this without patching the chart. Hence this issue.
Environment
- Chart:
jfrog/xray 103.143.27 (also confirmed on 103.143.30 and master)
- Xray appVersion 3.143.x
- Single-node Kubernetes; single-pod Xray (
splitXraytoSeparateDeployments.fullSplit=false)
sbom.enabled: true
Chart:
jfrog/xray(stable/xray)Chart versions affected: 103.143.27 → 103.143.30, and current
master(the relevant helper is identical across all of them)Type: Bug
Summary
Enabling the SBOM microservice via
sbom.enabled: truecorrectly renders thexray-sbomcontainer into the Xray StatefulSet, and the service registers with the router at startup. However, the router's required-service-types list —JF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES, produced by thexray.router.requiredServiceTypeshelper — is a hardcoded literal that does not includejfxsbm, regardless ofsbom.enabled.As a result the router logs a warning at registration and, on a router-only restart, silently drops the sbom service from its topology and does not re-register it (it only recovers on a full pod roll). There is no supported values-level way to fix this.
Steps to reproduce
Observed output:
Expected behavior
When
sbom.enabled: true, the sbom service type (jfxsbm) should be included inJF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES(as it is a first-class service in the pod), so the router treats it as a required, restart-durable service — consistent with how the container itself is gated onsbom.enabled.Actual behavior
jfxsbmis absent from the required set. At runtime the router logs (single-pod,splitXraytoSeparateDeployments.fullSplit=false):And it is accurate. Restarting only the router container (the other containers, including
xray-sbom, keep running):jfxsbmis removed from the topology and never re-registers on its own (verified over several minutes). The router then returns 404 for requests routed to the sbom service. Only a full pod restart re-registers it. (Async SBOM work off RabbitMQ continues; it is the router-fronted routing that is lost.)Root cause
stable/xray/templates/_helpers.tpl:The helper receives the root context (
.) from the StatefulSet ({{ include "xray.router.requiredServiceTypes" . }}) but ignores it and emits a constant. It never consults.Values.sbom.enabled, so enabling sbom cannot influence the router's required-types string. (Thexray.router.ipa.requiredServiceTypesvariant has the same shape.)Suggested fix
Make the helper conditionally append
jfxsbmwhen the sbom service is enabled — mirroring the{{- if .Values.sbom.enabled }}gate already used for the container inxray-statefulset.yaml:(If other optionally-enabled service types exist, the same pattern applies — the required-types list should be derived from the set of enabled services rather than a fixed literal.)
Workarounds attempted (and why they don't work)
router.extraEnvVars(re-declaringJF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES): the chart appendsextraEnvVarsafter its own entry, producing a duplicate env key.helm upgrade(server-side apply) rejects it:failed to create typed patch object ... .spec.template.spec.containers[name="router"].env: duplicate entries for key [name="JF_ROUTER_TOPOLOGY_LOCAL_REQUIREDSERVICETYPES"]requiredServiceTypes(nooptionalServiceTypes).So there is no clean way for a chart consumer to correct this without patching the chart. Hence this issue.
Environment
jfrog/xray103.143.27 (also confirmed on 103.143.30 andmaster)splitXraytoSeparateDeployments.fullSplit=false)sbom.enabled: true