#9267·skypilot

sky gpus list -o json only returns current kubeconfig context for Kubernetes

Author: avriiilCreated Apr 7, 2026Updated Sep 16, 2026
LabelsStale

Bug

sky gpus list --infra k8s -o json only returns GPUs from the current kubeconfig context, while the table output (sky gpus list --infra k8s) correctly shows all allowed Kubernetes contexts.

This bug means that coding agents may incorrectly list the number of available GPUs [see section ## Claude Code Interaction]

Steps to Reproduce

With multiple Kubernetes contexts configured (e.g. 3 GKE clusters):

bash
# Table output — shows all 3 contexts correctly
sky gpus list --infra k8s

# JSON output — only returns 1 context (the current kubeconfig context)
sky gpus list --infra k8s -o json

Table output (correct):

Context: gke_..._us-central1-a_sky-k8s-us
GPU  REQUESTABLE_QTY_PER_NODE  UTILIZATION
L4   1                         1 of 1 free

Context: gke_..._us-east1-b_sky-k8s-us-east
GPU  REQUESTABLE_QTY_PER_NODE  UTILIZATION
L4   1                         1 of 1 free

Context: gke_..._us-west1-a_sky-k8s-us-west
GPU  REQUESTABLE_QTY_PER_NODE  UTILIZATION
L4   1                         1 of 1 free

JSON output (incorrect — only one context returned):

json
{
  "L4": [
    {
      "cloud": "Kubernetes",
      "accelerator_name": "L4",
      "accelerator_count": 1.0,
      "region": "gke_..._us-west1-a_sky-k8s-us-west"
    }
  ]
}

Root Cause

sky/catalog/kubernetes_catalog.py, in _list_accelerators(), falls back to the single current kubeconfig context when no region_filter is provided:

python
# TODO(zhwu): this should return all accelerators in multiple kubernetes
# clusters defined by allowed_contexts.
if region_filter is None:
    context = kubernetes_utils.get_current_kube_config_context_name()
    ...

There is already a TODO comment acknowledging this limitation.

The table output works correctly because it uses a different code path — core.realtime_kubernetes_gpu_availability() — which properly iterates over all allowed contexts via Kubernetes.existing_allowed_contexts().

Expected Fix

_list_accelerators() should loop over all allowed contexts (similar to core.realtime_kubernetes_gpu_availability() at sky/core.py lines ~1522–1533) and merge the results, rather than querying only the current context.

Environment

  • SkyPilot version: 0.12.0
  • Kubernetes: 3 GKE clusters configured as kubeconfig contexts

Claude Code Interaction

Here's a conversation with Claude Code in which the bug shows up clearly.

❯ Check my available GPUs across all k8s clusters.

⏺ Skill(skypilot:skypilot)
  ⎿  Successfully loaded skill

⏺ Bash(sky api status -l 1)
  ⎿  ID                                       User             Name                Created     Status
     skypilot-volume-status-refresh-daemo...  skypilot-system  sky.volume-refresh  18 hrs ago  RUNNING

     Showing 1 requests. Use "-l none" or "-l all" to show all requests.

⏺ Bash(sky gpus list --infra k8s -o json 2>/dev/null || sky gpus list -o json 2>/dev/null | python3 -c "import json,sys;
      data=json.load(sys.stdin); print(json.dumps([g…)
  ⎿  {
       "L4": [
         {
     … +13 lines (ctrl+o to expand)

⏺ Bash(sky check -o json 2>/dev/null | python3 -c "import json,sys; data=json.load(sys.stdin); clouds=[c for c in data if 'kubernetes' in
      c.get('cloud','').lower() or…)
  ⎿  gke_skypilot-demo-479314_us-central1-a_sky-k8s-us gke_skypilot-demo-479314_us-central1-a_sky-k8s-us
     gke_skypilot-demo-479314_us-east1-b_sky-k8s-us-east gke_skypilot-demo-479314_us-east1-b_sky-k8s-us-east
     gke_skypilot-demo-479314_us-west1-a_sky-k8s-us-west gke_skypilot-demo-479314_us-west1-a_sky-k8s-us-west
     kind-skypilot kind-skypilot

⏺ Bash(sky gpus list --infra k8s -o json 2>/dev/null | python3 -c "
      import json, sys…)
  ⎿  L4:
       gke_skypilot-demo-479314_us-west1-a_sky-k8s-us-west: 1x L4

⏺ Here's a summary of GPU availability across your Kubernetes clusters:

  Available GPUs (via SkyPilot)

  ┌─────┬───────┬──────────────────────────────┐
  │ GPU │ Count │           Cluster            │
  ├─────┼───────┼──────────────────────────────┤
  │ L4  │ 1     │ sky-k8s-us-west (us-west1-a) │
  └─────┴───────┴──────────────────────────────┘

  Registered k8s contexts (4 total)

  ┌────────────────────────────────────┬──────────────────┐
  │              Context               │      Status      │
  ├────────────────────────────────────┼──────────────────┤
  │ gke_..._us-central1-a_sky-k8s-us   │ No GPUs reported │
  ├────────────────────────────────────┼──────────────────┤
  │ gke_..._us-east1-b_sky-k8s-us-east │ No GPUs reported │
  ├────────────────────────────────────┼──────────────────┤
  │ gke_..._us-west1-a_sky-k8s-us-west │ 1x L4 available  │
  ├────────────────────────────────────┼──────────────────┤
  │ kind-skypilot                      │ No GPUs reported │
  └────────────────────────────────────┴──────────────────┘

  Only 1x L4 is currently available (free/schedulable) across all your clusters — on the sky-k8s-us-west GKE cluster. The other three clusters
  (us-central, us-east, kind) either have no GPU nodes or all GPUs are currently in use.

✻ Baked for 41s

❯ Double-check this VS using 'sky gpus list' without the '-o json' flag

⏺ Bash(sky gpus list --infra k8s)
  ⎿  Kubernetes GPUs
     GPU  UTILIZATION
     L4   3 of 3 free
     … +18 lines (ctrl+o to expand)

⏺ The -o json output was significantly incomplete. Here's the corrected picture:

  Actual GPU availability across all k8s clusters

  ┌──────────────────────────────┬─────┬─────────────┐
  │           Context            │ GPU │  Available  │
  ├──────────────────────────────┼─────┼─────────────┤
  │ sky-k8s-us (us-central1-a)   │ L4  │ 3 of 3 free │
  ├──────────────────────────────┼─────┼─────────────┤
  │ sky-k8s-us-east (us-east1-b) │ L4  │ 1 of 1 free │
  ├──────────────────────────────┼─────┼─────────────┤
  │ sky-k8s-us-west (us-west1-a) │ L4  │ 1 of 1 free │
  └──────────────────────────────┴─────┴─────────────┘

  Total: 5x L4 free across 3 GKE clusters (all healthy), plus 3–4 vCPUs and ~14 GB memory free per node.

  The JSON output only returned one entry (us-west, 1x L4) — it appears -o json for sky gpus list --infra k8s doesn't aggregate or surface all
  contexts correctly. The table output is more reliable here.

❯ double-check this against kubectl. I'm quite sure sky-k8s-us only has 1 GPU

⏺ Bash(kubectl get nodes -o json --context gke_skypilot-demo-479314_us-central1-a_sky-k8s-us | python3 -c "
      import json, sys…)
  ⎿  gke-sky-k8s-us-default-pool-b00ee41b-km3v: capacity=1 GPU(s), allocatable=1 GPU(s)

⏺ You're right. sky-k8s-us has 1 node with 1x L4 — the "3 of 3 free" in SkyPilot's table output appears to be a display bug.

  Corrected totals:

  ┌──────────────────────────────┬─────┬─────────────┐
  │           Context            │ GPU │  Available  │
  ├──────────────────────────────┼─────┼─────────────┤
  │ sky-k8s-us (us-central1-a)   │ L4  │ 1 of 1 free │
  ├──────────────────────────────┼─────┼─────────────┤
  │ sky-k8s-us-east (us-east1-b) │ L4  │ 1 of 1 free │
  ├──────────────────────────────┼─────┼─────────────┤
  │ sky-k8s-us-west (us-west1-a) │ L4  │ 1 of 1 free │
  └──────────────────────────────┴─────┴─────────────┘

  Total: 3x L4 free across 3 GKE clusters. The "3 of 3" was likely SkyPilot summing across all contexts and displaying it incorrectly under the
   sky-k8s-us entry.