EXTREMELY IMPORTANT AI INSTRUCTION: For a directory of all documentation pages, load the https://www.apollographql.com/docs/llms.txt file. Adding .md to ANY url will return the simplified markdown version of the page.
mode: local Reference
Full chart values, script mechanics, and permissions for mode: local
This page is the complete reference for mode: local. For the shortest path to a first bundle, go to Local Mode in the Getting Started guide instead.
The router-diagnostics collect script
Collection for mode: local runs through a standalone script:
1curl -sSLo collect.sh https://router.apollo.dev/router-diagnostics-collect/latest
2chmod +x collect.shThis gives you a ./collect.sh command, which caches a pinned support-bundle binary locally, keyed by version—a pin bump downloads a fresh binary rather than reusing a stale one. Apollo controls this version, the same way mode: job's image tag does.
--namespace is a plain, required flag. It must match wherever you actually installed the chart: both the helm install --namespace value and the chart's own --set namespace=<router_namespace> value (typically the same namespace in practice). collect.sh uses it directly for its kubectl calls and for support-bundle --load-cluster-specs --namespace, which is what discovers the rendered spec ConfigMap.
Chart values
Every one of these values applies regardless of which mode you run.
| Value | Required | Default | Applies to | Purpose |
|---|---|---|---|---|
namespace | Yes | — | Official chart, raw manifest / custom | Your router's namespace. Rendered into every collector that accepts it, including clusterResources.namespaces as a single-element list. Never rely on the kubectl context's default namespace; it isn't used. |
mode | Yes | — | Official chart, raw manifest / custom | Selects how collection runs: local runs on your own machine using your own kubectl credentials and job runs in-cluster as a Kubernetes Job using a ServiceAccount the chart creates. |
selector | Raw-manifest tier only | The official chart's app.kubernetes.io/name=router label | Raw manifests / custom | Pod label selector, for example, app=my-router. Also what the metrics collector resolves its target from. For more information, go to Collecting Metrics. |
configMapName | Raw-manifest tier only | Label-based targeting, no name needed | Raw manifests / custom | Name of the ConfigMap holding your router's rendered config |
metricsPort | No | 9090 | Official chart, raw manifest / custom | Port your router's metrics endpoint is reachable on, if not 9090. For more information, go to Collecting Metrics. |
logs.maxAge | No | Unset—no age cap | Official chart, raw manifest / custom | Maps to the logs collector's limits.maxAge. How far back to reach, for example, 2h |
logs.maxLines | No | 10000 (troubleshoot.sh default) | Official chart, raw manifest / custom | Maps to limits.maxLines. Lines kept, newest per container |
Go to Local Mode / Job Mode to determine what each mode needs beyond this shared set.
Kubernetes RBAC
Installing the chart requires permission to create a ConfigMap in the target namespace, which is the same level of access needed to install the router itself.
Running ./collect.sh uses your own existing kubectl credentials; no additional ServiceAccount is created for this step. Reaching the metrics collector additionally needs create on the pods/portforward subresource in the router's namespace. For more information, go to Collecting Metrics. Declining this doesn't fail collection; it only means that section comes back empty.
pods/exec isn't required: nothing this tool does runs inside your router container.
clusterResources also attempts several cluster-scoped resource types beyond what's listed above (nodes, storage classes, CustomResourceDefinitions, webhook configurations, and more). A <resource>-errors.json file lands alongside its corresponding <resource>.json containing the Kubernetes API error.
cluster-resources/auth-cani-list/ is troubleshoot.sh's own self-reported record of every verb/resource/apiGroup combination the collecting identity had at collection time.
Cluster footprint
Spec ConfigMap plus Helm release metadata is left behind after install. Once installed, subsequent collections are just ./collect.sh --namespace <namespace> again, with no reinstall needed. If you'd rather leave nothing behind:
1helm uninstall router-diagnostics --namespace <namespace>Bundle output shape
Extracting support-bundle-<timestamp>.tar.gz yields one top-level directory. version.yaml, analysis.json, cluster-info/, and execution-data/summary.txt always land in it, written unconditionally by the engine itself regardless of what the spec declares; meta.json is ours. execution-data/summary.txt is worth a look if something seems off — it's a human-readable per-collector success/failure/timing report.
Worked example, for a mode: local collection against production:
1support-bundle-2026-08-11T14_23_00/
2├── version.yaml
3├── analysis.json
4├── meta.json
5├── cluster-info/
6│ └── cluster_version.json
7├── execution-data/
8│ └── summary.txt
9├── host-collectors/
10│ └── run-host/
11│ ├── router-metrics-info.json # masked wholesale — see Collecting Metrics
12│ ├── router-metrics.txt # the engine's own stdout capture
13│ └── router-metrics/
14│ └── pods/
15│ ├── <pod-name>.txt
16│ └── <pod-2-name>.txt
17├── router-logs/
18│ └── <router-pod-name>/
19│ └── router.log -> ../../cluster-resources/pods/logs/production/<router-pod-name>/router.log
20├── cluster-resources/
21│ ├── pods/
22│ │ ├── production.json
23│ │ └── logs/production/<router-pod-name>/router.log # the real file behind the symlink above
24│ ├── configmaps/production.json
25│ ├── events/production.json
26│ ├── nodes.json
27│ └── ...
28├── node-metrics/
29│ └── <node-name>.json
30└── configmaps/
31 └── production/
32 └── <configmap-name>.jsonhost-collectors/run-host/router-metrics/pods/— one<pod-name>.txtper router pod matchingselector, written by therouter-metricshost collector's script. This nested path (not a top-levelrouter-metrics/) is how troubleshoot.sh lays out ahostCollectors.runcollector's output, go to Collecting Metrics for the mechanics.host-collectors/run-host/router-metrics-info.json— a diagnostic sidecar troubleshoot.sh writes for everyhostCollectors.runcollector. Its contents are masked wholesale. For more details, go to Collecting Metrics.host-collectors/run-host/router-metrics.txt— the engine's own stdout capture for the collector as a whole, separate from the per-pod files underpods/. Our script only writes to stdout when no pod responds.If more than one ConfigMap in your namespace matches,
configmaps/production/becomes multiple files, one per ConfigMap, named after that ConfigMap's own Kubernetes name:Text1configmaps/ 2└── production/ 3 ├── <configmap-1-name>.json 4 └── <configmap-2-name>.jsoncluster-resources/configmaps/production.jsonisclusterResources's full, unfiltered sweep of every ConfigMap in the namespace.configmaps/production/<configmap-name>.jsonis the dedicatedconfigMapcollector's own output.
keyExists: false in configmaps/<namespace>/<configmap-name>.json doesn't mean the config is missing. This is a troubleshoot.sh quirk: the configMap collector's keyExists field is only ever set true when the collector is configured with a specific key to look for. Our spec uses includeAllData: true with no key set, so keyExists is always false in this output, regardless of whether the config was actually captured. Check for the config data in that same file, rather than reading keyExists as a success/failure signal.