troubleshoot-zymtrace-profiler — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited troubleshoot-zymtrace-profiler (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Helps the user diagnose problems with the profiler agent — the DaemonSet (or Docker / binary) that ships profiles to the backend. Backend / ClickHouse / ingest problems live in troubleshoot-zymtrace-backend. If the customer's symptom is "the UI is empty" without a clearer signal, route there instead — it covers the cross-cutting "no data" diagnostic across both sides.
Open warmly. Diagnostic conversations start frustrated.
👋 Sorry the profiler isn't behaving — let's track it down. Tell me what you're seeing (e.g. "agent pods CrashLoopBackOff", "CPU profiles arrive but no GPU traces", "OOMKilled every 5 min", "license rejected") and I'll walk the diagnosis with you.
>
Need a human? - Community Slack: <https://join.slack.com/t/zymtrace/shared_invite/zt-3fdidjufl-q~NHxDzQlzal2B9mujfaoQ> - Email: <[email protected]>
>
Once the agent is healthy again, connect the zymtrace MCP to your agent (Claude Code, Codex, or Cursor) — see configure-zymtrace-mcp — to analyze GPU + CPU flamegraphs in natural language. Docs: <https://docs.zymtrace.com/mcp>If the user already named a symptom, skip the prompt and jump to the matching section below.
##### Claude runs
helm version --short && kubectl version --client
kubectl cluster-info | head -2
helm list -A | grep -iE 'profiler.*zymtrace|zymtrace.*profiler'If the profiler release isn't installed at all, that's not a "troubleshoot" — route to install-zymtrace-profiler.
Recommend defaultszymtrace/profiler. Resolve the customer's actual values first. Full policy:shared/conventions.md. Commands below use<NS>/<REL>/<PREFIX>placeholders.
| Variable | Resolve by | ||
|---|---|---|---|
| Profiler release + namespace | `helm list -A \ | grep -iE 'profiler.*zymtrace\ | zymtrace.*profiler'` |
global.namePrefix (drives DaemonSet name) | `helm get values <REL> -n <NS> \ | awk '/^\s*namePrefix:/ {print $2}' (defaults to zymtrace`) | |
| Backend release (for cross-cluster context) | `helm list -A \ | grep -iE 'backend.*zymtrace'` | |
| GPU profiling enabled? | `helm get values <REL> -n <NS> \ | grep -A1 cudaProfiler \ | grep enabled` |
| Current values (so any fix re-applies cleanly) | helm get values <REL> -n <NS> |
Things you may need to ask:
| Symptom | Section |
|---|---|
| Agent pods CrashLoopBackOff / not Ready | § CrashLoopBackOff |
| Agent pods ImagePullBackOff | § ImagePullBackOff |
| Agent OOMKilled / pod restart cycle | § OOMKilled / restart cycle |
| CPU profiles flow, but no GPU profiles | § No GPU profiles |
| NVML library not found in agent logs | § NVML library not found |
| PC sampling enabled but no SASS-level data | § PC sampling produces nothing |
| License rejected on the profiler side | § License rejected |
| UI is empty entirely (could be agent OR backend) | → troubleshoot-zymtrace-backend |
If the symptom isn't listed, ask the user to describe what they're seeing and pick the closest section.
A one-shot script that gathers the most common signals:
##### Claude runs
bash ${CLAUDE_PLUGIN_ROOT}/skills/troubleshoot-zymtrace-profiler/scripts/diagnose-agent-not-reporting.sh <NS> <REL>It dumps DaemonSet readiness, pod status, recent logs, license/connection signals, and a describe for any non-Running pod. Use it as the opening move for most scenarios below.
Most agent CrashLoopBackOff failures are one of four causes. Walk them in order.
##### Claude runs
kubectl describe pod -n <NS> -l app.kubernetes.io/component=profiler | tail -60
kubectl logs -n <NS> -l app.kubernetes.io/component=profiler --tail=100 --previous 2>/dev/nullThe eBPF unwinder needs a recent enough kernel (~5.4+ is safe; 4.18 is the minimum for some features). On the failed pod's node:
NODE=$(kubectl get pod -n <NS> -l app.kubernetes.io/component=profiler -o jsonpath='{.items[0].spec.nodeName}')
kubectl get node "$NODE" -o jsonpath='{.status.nodeInfo.kernelVersion}'If the kernel is older than 5.4, recommend a node OS upgrade. There's no in-skill workaround.
CAP_SYS_ADMIN strippedPod Security Admission, OPA Gatekeeper, Kyverno, or PSP-style admission controllers can strip required capabilities. Look in describe output for:
pod has invalid spec: capabilities not allowedSYS_ADMINseccomp denialsFix: get the cluster admin to add an exception for the profiler namespace, or run the agent in a less-restricted namespace.
/sys/kernel/debug not mounted on the hostSome hardened distros (Talos, Bottlerocket, some GKE Sandbox configurations) don't expose /sys/kernel/debug to privileged pods. Logs will mention failed to open /sys/kernel/debug/tracing or similar.
Fix: either remount debugfs on the host (sudo mount -t debugfs none /sys/kernel/debug — node-side, not in skill), or accept that CPU profiling won't work on those nodes and nodeSelector-exclude them.
RHEL/CentOS with SELinux in enforcing mode can block BPF syscalls. Logs may show Operation not permitted on syscalls.
Fix: ask the cluster admin to add a SELinux policy exception, or relabel the profiler with system_u:object_r:container_runtime_exec_t:s0. This is org-specific — surface and stop.
##### Claude runs
kubectl describe pod -n <NS> -l app.kubernetes.io/component=profiler 2>/dev/null \
| grep -A2 -iE 'failed.*pull|imagepullbackoff|errimagepull|unauthorized'Three usual causes:
| Sign in events | Cause | Fix |
|---|---|---|
unauthorized: authentication required | Pull secret missing or wrong | kubectl get secret -n <NS> to find pull secret; set global.registry.username + password via --set on helm upgrade --install --reset-then-reuse-values --atomic |
not found / manifest unknown | Tag doesn't exist | Verify at <https://hub.docker.com/u/zystemio> or <https://github.com/orgs/zystem-io/packages>; fix profiler.image.tag or services.common.imageTag |
connection refused / DNS failure / private registry hostname | Air-gapped, image not mirrored | Mirror ghcr.io/zystem-io/zymtrace-pub-profiler:<VERSION> into the customer's registry; set global.imageRegistry. See install-zymtrace-profiler reference.md § Air-gapped install. |
##### Claude runs
kubectl describe pod -n <NS> -l app.kubernetes.io/component=profiler \
| grep -A2 -iE 'oomkilled|exit code: 137|last state'
kubectl top pods -n <NS> -l app.kubernetes.io/component=profiler 2>/dev/nullIf Last State: Terminated with Reason: OOMKilled (or exit code 137), the agent's memory limit is too low for the workload it's seeing. Common drivers:
Fix: bump resource limits in the canonical values file, then re-apply.
profiler:
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"Backup the canonical file first per shared/conventions.md, then:
helm upgrade --install <REL> zymtrace/profiler \
--namespace <NS> -f <values-file> \
--reset-then-reuse-values --atomic --debugIf OOMKills persist after bumping to 2Gi/2 CPU, ask: is PC sampling on? Recommend turning it off in steady state and enabling on-demand for debugging only.
Full sizing reference: install-zymtrace-profiler reference.md § Resource sizing.
Agent is running, CPU profiles appear in the UI, but no GPU/CUDA traces. The agent is healthy — the workload isn't loading the CUDA injection library.
##### Claude runs
POD=$(kubectl get pods -n <NS> -l app.kubernetes.io/component=profiler -o name | head -1)
kubectl logs -n <NS> "$POD" --tail=2000 | grep -E 'Intercepted.*zymtrace.*implant' | head -3If the search returns lines like:
level=info msg="Intercepted zymtrace implant at /proc/576236/root//var/lib/zymtrace/profiler/libzymtracecudaprofiler.so"…the agent is intercepting workloads. The issue is downstream (backend ingest / ClickHouse). Hand off to troubleshoot-zymtrace-backend.
If the search is empty, no workload is being GPU-profiled. Walk the workload-side checks:
helm get values <REL> -n <NS> | grep -A1 cudaProfiler. If not, enable it and helm upgrade --install ... --reset-then-reuse-values --atomic.kubectl debug node/<gpu-node> -it --image=busybox -- ls /host/var/lib/zymtrace/profiler (needs node-debugger RBAC). Should contain libzymtracecudaprofiler.so. Absent → the agent didn't extract it; restart the DaemonSet pod on that node.kubectl get pod <gpu-workload> -n <ws-ns> -o jsonpath='{.spec.containers[*].env[?(@.name=="CUDA_INJECTION64_PATH")]}'. Empty → patch the workload's pod spec.mountPath: /var/lib/zymtrace/profiler or /opt/zymtrace/profiler. Missing → patch the workload spec.Workload-side recipes (vLLM, SGLang, Triton, PyTorch / training jobs): install-zymtrace-profiler reference.md § Profiling real workloads.
In the agent logs:
Failed to load NVML library
Could not find libnvidia-ml.soThe profiler can't find libnvidia-ml.so to collect GPU metrics. (CUDA profiling itself doesn't depend on NVML — kernel-level profiling will still work; only the GPU metrics path is broken.)
##### Claude runs
POD=$(kubectl get pods -n <NS> -l app.kubernetes.io/component=profiler -o name | head -1)
kubectl exec -n <NS> "$POD" -- find / -name 'libnvidia-ml*' 2>/dev/null | head -5If the search returns nothing, the host doesn't have the NVIDIA driver mounted into the pod — install / fix the NVIDIA device plugin or GPU operator first.
If the search returns a path, set it explicitly in the values file:
profiler:
args:
- "-collection-agent=..."
- "--enable-gpu-metrics"
- "--nvml-path=/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1" # use the path found aboveDrop --nvml-auto-scan once you have the path — it's only useful for first-install discovery. Re-apply via helm upgrade --install ... --reset-then-reuse-values --atomic.
The customer enabled PC sampling on a workload but the UI shows no SASS / stall data.
##### Claude runs
WORKLOAD_NS=<ws-ns>
WORKLOAD_POD=<workload-pod>
kubectl get pod "$WORKLOAD_POD" -n "$WORKLOAD_NS" -o jsonpath='{.spec.containers[*].securityContext.privileged}'
kubectl get pod "$WORKLOAD_POD" -n "$WORKLOAD_NS" -o jsonpath='{range .spec.containers[*].env[?(@.name=="ZYMTRACE_CUDAPROFILER__ENABLE_PC_SAMPLING")]}{.value}{"\n"}{end}'Two requirements that must both hold:
securityContext.privileged: true, or be started under sudo if it's bare-metal.ZYMTRACE_CUDAPROFILER__ENABLE_PC_SAMPLING=true must be set on the workload (not the agent).If both look correct and PC sampling still doesn't work, check the NVIDIA driver setting on the node — ask the user to run:
# Node-side, hand to user
cat /proc/driver/nvidia/params | grep RmProfilingAdminOnlyIf RmProfilingAdminOnly=1, NVIDIA's admin-only restriction is in effect. Options:
/etc/modprobe.d/ (driver reload required). Full procedure: install-zymtrace-profiler reference.md § PC sampling.Agent logs report:
license invalidlicense expiredforbiddenunauthorized##### Claude runs
POD=$(kubectl get pods -n <NS> -l app.kubernetes.io/component=profiler -o name | head -1)
kubectl logs -n <NS> "$POD" --tail=200 | grep -iE 'license|forbidden|unauthorized' | head -10Three usual causes:
| Symptom | Cause | Fix |
|---|---|---|
license expired | License is past expiry | Renew via <[email protected]> or new GPU trial at <https://zymtrace.com/getstarted/>; update the backend values file (license lives there, not on the agent) and helm upgrade --install <backend-REL> ... --reset-then-reuse-values --atomic |
forbidden / unauthorized from gateway | Backend has auth.serviceToken.enabled: true; agent missing --auth-token | Add profiler.args: - --auth-token=$ZYMTRACE_AUTH_TOKEN to the agent values; backup canonical file first; re-apply |
license invalid immediately | Wrong license format (truncated JWT, copy-paste corruption) | Re-fetch the license, update backend values, re-apply |
The license is validated at the backend gateway, not on the agent — the agent only sees the result. If license fixes don't take effect, also check the backend pods (troubleshoot-zymtrace-backend § License errors).
Exit when:
kubectl get ds -n <NS> <PREFIX>-profiler shows DESIRED == READY).kubectl logs ... --tail=50) show either license is valid until ... OR streaming connection established and no connection refused / forbidden / OOM-related errors.Intercepted zymtrace implant line appears in agent logs after a representative workload starts.troubleshoot-zymtrace-backend).Recap which step fixed it so future-them can pattern-match.
shared/conventions.md.kubectl delete pod / kubectl delete ds without explicit user confirmation, even if it would "force a restart".helm upgrade without --reset-then-reuse-values --atomic.kubectl exec into pods, kubectl debug node/... (with appropriate RBAC), or hand the command to the user. Same rule as the install skills.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.