-
Notifications
You must be signed in to change notification settings - Fork 82
docs(troubleshooting): add scheduler filter reason code reference #767
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| --- | ||
| title: Scheduling Failures | ||
| sidebar_label: Scheduling Failures | ||
| --- | ||
|
|
||
| When a Pod that requests HAMi resources stays `Pending`, the HAMi scheduler extender has already made a decision and told you why. It records that decision as `FilteringFailed` events on the Pod, using a fixed set of reason codes such as `CardInsufficientMemory` or `CardTimeSlicingExhausted`. | ||
|
|
||
| This page explains how to read those messages and what each reason code means. | ||
|
|
||
| :::info | ||
|
|
||
| Reason codes are defined in `pkg/device/common/common.go` in the [HAMi repository](https://github.com/Project-HAMi/HAMi). The list below reflects HAMi v2.9.0. Older versions emit a subset of these codes; a Pod scheduled by an older scheduler may show free-form messages instead. | ||
|
|
||
| ::: | ||
|
|
||
| ## Step 1: Read the Pod events | ||
|
|
||
| ```bash | ||
| kubectl describe pod <pod-name> -n <namespace> | ||
| ``` | ||
|
|
||
| The `Events` section holds two different kinds of message. Both matter: | ||
|
|
||
| ```plaintext | ||
| Events: | ||
| Type Reason Age From Message | ||
| ---- ------ ---- ---- ------- | ||
| Warning FailedScheduling 15s default-scheduler 0/3 nodes are available: 3 NodeUnfitPod. | ||
| Warning FilteringFailed 16s hami-scheduler 2 nodes CardInsufficientMemory(node-a,node-b) | ||
| Warning FilteringFailed 16s hami-scheduler 1 nodes CardTypeMismatch(node-c) | ||
| ``` | ||
|
|
||
| - `FailedScheduling` comes from the Kubernetes scheduler. It only tells you how many nodes were rejected. | ||
| - `FilteringFailed` comes from `hami-scheduler` and carries the actual reason. **This is the line to act on.** | ||
|
|
||
| If you see no `FilteringFailed` event at all, the Pod never reached HAMi. Check that the Pod uses HAMi's scheduler and that the admission webhook is running. See [Verify HAMi](../get-started/verify-hami.md). | ||
|
|
||
| ## Step 2: Decode the message | ||
|
|
||
| ### The event format | ||
|
|
||
| ```plaintext | ||
| <node-count> nodes <ReasonCode>(<node-a>,<node-b>,...) | ||
| ``` | ||
|
|
||
| Three properties of this format are easy to misread: | ||
|
|
||
| - **One event per reason code.** A cluster where two nodes ran out of memory and one node had the wrong card type produces _two_ `FilteringFailed` events, not one. Read all of them before concluding anything. | ||
| - **These events appear only when no node fits.** If at least one node is viable, the Pod is scheduled and you get a single `FilteringSucceed` event instead, even though other nodes were rejected. | ||
| - **The node list is the set of nodes rejected for that specific reason.** A node can appear under more than one reason code, because different GPUs on the same node can fail for different reasons. | ||
|
|
||
| ### The scheduler log format | ||
|
|
||
| The events aggregate per node. To see which _device_ failed and why, read the scheduler extender log: | ||
|
|
||
| ```bash | ||
| kubectl logs -n kube-system deploy/hami-scheduler -c vgpu-scheduler-extender --tail=200 | ||
| ``` | ||
|
|
||
| At the default verbosity (`-v=4`) each rejected node produces one `NodeUnfitPod` line: | ||
|
|
||
| ```plaintext | ||
| NodeUnfitPod pod="default/gpu-pod" node="node-a" reason="3/8 CardInsufficientMemory, 5/8 CardInsufficientCore" | ||
| ``` | ||
|
|
||
| Read the fraction as `<devices rejected for this reason>/<total devices of that type on the node>`. In the line above, node-a has 8 GPUs: 3 were short on memory and 5 were short on compute. Each rejected device is counted once, under the **first** check it failed, so a card that is short on both memory and compute appears only under `CardInsufficientMemory`. Fixing the reason with the largest count is not always the fastest route to a scheduled Pod. | ||
|
|
||
| :::warning The one exception to the fraction rule | ||
|
|
||
| `AllocatedCardsInsufficientRequest` inverts the numerator. There it counts the cards that **did** fit, not the ones that were rejected. `2/8 AllocatedCardsInsufficientRequest` means the node offered 2 usable cards for a request that needed more. | ||
|
|
||
| ::: | ||
|
|
||
| Successful nodes log a matching `NodeFitPod` line with the score that decided the placement. | ||
|
|
||
| ## Step 3: Look up the reason code | ||
|
|
||
| ### Node-level rejections | ||
|
|
||
| | Reason code | What the scheduler found | What to do | | ||
| | --- | --- | --- | | ||
| | `NodeInsufficientDevice` | The node has fewer devices of the requested type than the Pod asks for. Evaluated before any per-device check. | Lower the card count, or add nodes with more cards. A 4-GPU request never fits a 2-GPU node, regardless of how idle it is. | | ||
| | `NodeUnfitPod` | Summary line: this node was rejected. It is always accompanied by the per-device reasons. | Read the per-device reasons in the same log line. | | ||
| | `NodeFitPod` | Not a failure. The node passed filtering and was scored. | Nothing. | | ||
|
|
||
| ### The card was excluded before capacity was considered | ||
|
|
||
| | Reason code | What the scheduler found | What to do | | ||
| | --- | --- | --- | | ||
| | `CardNotHealth` | The device plugin reported the device as unhealthy, so it is skipped entirely. | Check the device plugin logs and `nvidia-smi` on that node. An unhealthy card is a node problem, not a request problem. | | ||
| | `CardTypeMismatch` | The card model does not satisfy the Pod's type constraints. | Review the `nvidia.com/use-gputype` / `nvidia.com/nouse-gputype` annotations. Also triggered by `nvidia.com/vgpu-mode` when the card does not run the requested mode. See [Specify device type to use](../userguide/nvidia-device/specify-device-type-to-use.md). | | ||
| | `CardUuidMismatch` | The card's UUID is excluded by the Pod's UUID constraints. | Review `nvidia.com/use-gpuuuid` / `nvidia.com/nouse-gpuuuid`. A stale UUID pinned in a Deployment template survives node replacement and silently blocks every rescheduling attempt. See [Specify device UUID to use](../userguide/nvidia-device/specify-device-uuid-to-use.md). | | ||
| | `NumaNotFit` | The Pod requires all its cards on one NUMA node, and the candidate cards span a NUMA boundary. | Only applies when the Pod sets `nvidia.com/numa-bind: "true"`. Drop the annotation if NUMA locality is not required, or request a card count that a single NUMA node can serve. | | ||
| | `ModeNotFit` | The node cannot run the requested virtualization mode for that vendor. | Vendor-specific. On Ascend, it means HAMi-core sharing was requested on a node that does not support it; on Enflame, that no GCU profile matches the request. | | ||
| | `CardNotFoundCustomFilterRule` | A vendor-specific filter rule rejected the card. | Consult the guide for that vendor under [User Guide](../userguide/device-supported.md). NVIDIA cards outside MIG mode never produce this code. | | ||
| | `CardMigTopologyInfeasible` | The card is in MIG mode, but no allowed MIG profile with a free placement matches the requested memory. | The card may have free memory in total while still having no contiguous slot of the right shape. Align the request with a real MIG profile size, or drain the card. See [Dynamic MIG support](../userguide/nvidia-device/dynamic-mig-support.md). | | ||
|
|
||
| ### The card matched but had no room | ||
|
|
||
| | Reason code | What the scheduler found | What to do | | ||
| | --- | --- | --- | | ||
| | `CardInsufficientMemory` | Free device memory is below the request: `total - used < requested`. | The most common code. Lower `nvidia.com/gpumem`, wait for a workload to finish, or add capacity. Remember that HAMi counts _allocated_ memory, not memory currently in use, so an idle-looking card can still be full. | | ||
| | `CardInsufficientCore` | Free compute percentage is below `nvidia.com/gpucores`. | Lower `gpucores`, or place the Pod on a card with fewer streaming workloads. | | ||
| | `CardTimeSlicingExhausted` | The card already hosts the maximum number of tasks. | Each card accepts `deviceSplitCount` tasks (default 10) regardless of remaining memory. A card with plenty of free memory still rejects task 11. Raise the split count if the workloads are small enough to justify it. See [Global configuration](../userguide/configure.md). | | ||
| | `CardComputeUnitsExhausted` | The Pod requests no cores at all, and the card's compute is fully committed. | A request that omits `gpucores` is not free to place: it still cannot land on a card at 100% committed compute. Give the Pod an explicit `gpucores` value, or free compute on the card. | | ||
| | `ExclusiveDeviceAllocateConflict` | Exclusive use was requested for a card that is already shared, or a shared request hit a card held exclusively. | Raised either when `nvidia.com/gpucores: 100` is requested on a card with existing tasks, or when the `mutex` GPU scheduler policy is in effect. See [Scheduling policy](../userguide/nvidia-device/scheduling-policy.md). | | ||
| | `ResourceQuotaNotFit` | The allocation would exceed the namespace's HAMi `ResourceQuota`. | A cluster-capacity problem in disguise: the cards are free, the namespace budget is not. See [Using ResourceQuota](../userguide/nvidia-device/using-resourcequota.md). | | ||
|
Comment on lines
+106
to
+107
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(scheduling-failures\.md|device\.go)$|nvidia/.*/device\.go$' | head -80
printf '%s\n' '--- documentation context ---'
for f in docs/troubleshooting/scheduling-failures.md \
i18n/zh/docusaurus-plugin-content-docs/current/troubleshooting/scheduling-failures.md; do
if [ -f "$f" ]; then
printf '\n--- %s ---\n' "$f"
sed -n '1,145p' "$f"
fi
done
printf '%s\n' '--- local reason-code references ---'
rg -n -C 3 'ExclusiveDeviceAllocateConflict|ResourceQuotaNotFit|mutex|gpucores' --glob '*.go' --glob '*.md' --glob '*.yaml' --glob '*.yml' . | head -300Repository: Project-HAMi/website Length of output: 48176 🏁 Script executed: #!/bin/bash
set -eu
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
for spec in \
"device.go|https://raw.githubusercontent.com/Project-HAMi/HAMi/refs/tags/v2.9.0/pkg/device/nvidia/device.go" \
"score.go|https://raw.githubusercontent.com/Project-HAMi/HAMi/refs/tags/v2.9.0/pkg/scheduler/score.go" \
"common.go|https://raw.githubusercontent.com/Project-HAMi/HAMi/refs/tags/v2.9.0/pkg/device/common/common.go"; do
name="${spec%%|*}"
url="${spec#*|}"
if curl -fsSL "$url" -o "$tmpdir/$name"; then
printf '\n--- %s ---\n' "$url"
rg -n -C 8 'ExclusiveDeviceAllocateConflict|mutex|gpucores|used' "$tmpdir/$name" || true
else
printf '\n--- unavailable: %s ---\n' "$url"
fi
done
printf '\n--- all v2.9.0 source paths mentioning the reason ---\n'
api='https://api.github.com/repos/Project-HAMi/HAMi/git/trees/v2.9.0?recursive=1'
curl -fsSL "$api" |
jq -r '.tree[] | select(.type == "blob") | .path' |
while read -r path; do
case "$path" in
*.go)
url="https://raw.githubusercontent.com/Project-HAMi/HAMi/refs/tags/v2.9.0/$path"
body="$(curl -fsSL "$url" 2>/dev/null || true)"
if printf '%s' "$body" | grep -q 'ExclusiveDeviceAllocateConflict'; then
printf '%s\n' "$path"
printf '%s' "$body" | grep -n -C 8 'ExclusiveDeviceAllocateConflict'
fi
;;
esac
doneRepository: Project-HAMi/website Length of output: 4657 🌐 Web query:
💡 Result: In the context of the Project-HAMi (HAMi) project, ExclusiveDeviceAllocateConflict is a scheduling failure reason indicating that a container’s request for exclusive device access cannot be satisfied because the targeted device is already in use [1][2][3]. The mention of mutex in relation to this conflict refers to a specific GPU scheduling policy introduced to enforce exclusive access [4]. When a pod sets the annotation hami.io/gpu-scheduler-policy to mutex, the HAMi scheduler is instructed to allocate only those GPUs that have no existing users (where the usage count is 0) [4]. Key points regarding this functionality include: 1. Policy Enforcement: The mutex policy ensures that if a device is already occupied (Used > 0), the scheduler's Fit function will reject that device, triggering the ExclusiveDeviceAllocateConflict reason [4][3]. 2. Diagnostic Clarity: In earlier versions, this conflict was sometimes misreported as other errors (such as NumaNotFit) [4]. Updates were implemented to ensure that the ExclusiveDeviceAllocateConflict reason is explicitly reported when the mutex policy restricts device allocation, improving diagnostic clarity for users [4][5]. 3. Reporting: This reason appears in scheduler logs and event messages when the system determines that a node or device cannot fulfill the pod's requirement for exclusive access due to current device occupancy [1][6]. While v2.9.0 is a specific release version of HAMi [7], the ExclusiveDeviceAllocateConflict reason is a persistent part of the HAMi scheduling diagnostic framework, used across multiple versions to signify that a requested exclusive device is unavailable [1][8][2]. Citations:
🏁 Script executed: #!/bin/bash
set -eu
base='https://api.github.com/repos/Project-HAMi/HAMi'
commit='06d9b907f19e78551d616e106209d2a98ec20f01'
printf '%s\n' '--- cited commit metadata ---'
curl -fsSL "$base/commits/$commit" |
jq -r '[.sha, .commit.message, (.files | length | tostring)] | `@tsv`'
printf '%s\n' '--- cited commit file patches ---'
curl -fsSL "$base/commits/$commit" |
jq -r '.files[] | select((.patch // "") | test("ExclusiveDeviceAllocateConflict|gpu-scheduler-policy|mutex")) |
"\nFILE: \(.filename)\n\(.patch)"'
printf '%s\n' '--- v2.9.0 tag resolution ---'
curl -fsSL "$base/git/ref/tags/v2.9.0" |
jq -r '"type=\(.object.type) sha=\(.object.sha)"'Repository: Project-HAMi/website Length of output: 399 🏁 Script executed: #!/bin/bash
set -eu
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT
for url in \
'https://github.com/Project-HAMi/HAMi/commit/06d9b907f19e78551d616e106209d2a98ec20f01.patch' \
'https://github.com/Project-HAMi/HAMi/commit/06d9b907f19e78551d616e106209d2a98ec20f01.diff'; do
printf '\n--- %s ---\n' "$url"
if curl -fsSL "$url" -o "$tmp"; then
rg -n -C 12 'ExclusiveDeviceAllocateConflict|gpu-scheduler-policy|mutex|Fit\(' "$tmp" || cat "$tmp"
else
printf '%s\n' 'unavailable'
fi
done
printf '\n--- v2.9.0 NVIDIA policy-related source references ---\n'
for path in \
pkg/device/nvidia/device.go \
pkg/device/nvidia/nvidia.go \
pkg/device/nvidia/nvidia_test.go \
pkg/device/common/common.go \
pkg/device/device.go \
pkg/scheduler/scheduler.go \
pkg/scheduler/score.go; do
url="https://raw.githubusercontent.com/Project-HAMi/HAMi/refs/tags/v2.9.0/$path"
body="$(curl -fsSL "$url" 2>/dev/null || true)"
if [ -n "$body" ]; then
hits="$(printf '%s' "$body" | rg -n -C 6 'ExclusiveDeviceAllocateConflict|gpu-scheduler-policy|mutex|NodeLockNvidia' || true)"
if [ -n "$hits" ]; then
printf '\nFILE: %s\n%s\n' "$path" "$hits"
fi
fi
doneRepository: Project-HAMi/website Length of output: 50377 🏁 Script executed: #!/bin/bash
set -eu
python3 - <<'PY'
from urllib.request import urlopen
tag_url = "https://raw.githubusercontent.com/Project-HAMi/HAMi/refs/tags/v2.9.0/pkg/device/nvidia/device.go"
patch_url = "https://github.com/Project-HAMi/HAMi/commit/06d9b907f19e78551d616e106209d2a98ec20f01.patch"
tag = urlopen(tag_url).read().decode()
patch = urlopen(patch_url).read().decode()
tag_conflict = "if dev.Totalcore == 100 && k.Coresreq == 100 && dev.Used > 0"
tag_mutex_guard = "if isMutex && dev.Used > 0"
patch_nvidia_mutex = "+\t\tif isMutex && dev.Used > 0"
patch_reason = "+\t\t\treason[common.ExclusiveDeviceAllocateConflict]++"
print("v2.9.0 contains exclusive-used guard:", tag_conflict in tag)
print("v2.9.0 contains mutex guard:", tag_mutex_guard in tag)
print("later patch adds NVIDIA mutex guard:", patch_nvidia_mutex in patch)
print("later patch reports ExclusiveDeviceAllocateConflict for mutex:", patch_reason in patch)
print("v2.9.0 conflict-branch count:", tag.count("reason[common.ExclusiveDeviceAllocateConflict]++"))
PYRepository: Project-HAMi/website Length of output: 2444 Remove the unsupported In HAMi v2.9.0, the NVIDIA implementation emits
📍 Affects 2 files
🤖 Prompt for AI AgentsSource: MCP tools |
||
| | `AllocatedCardsInsufficientRequest` | Some cards on the node fit, but fewer than the requested count. | The node is partially usable. Reduce the card count, or free enough cards on one node. HAMi does not split one container's cards across nodes. | | ||
|
|
||
| ## Step 4: Get per-device detail when the node summary is not enough | ||
|
|
||
| The `NodeUnfitPod` summary tells you _how many_ devices failed, not _which_ ones. Device identity is logged at `-v=5`: | ||
|
|
||
| ```bash | ||
| helm upgrade hami hami-charts/hami \ | ||
| --namespace kube-system \ | ||
| --reuse-values \ | ||
| --set-json 'scheduler.extender.extraArgs=["--debug","-v=5"]' | ||
|
|
||
|
Comment on lines
+115
to
+119
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- target files ---'
for f in \
docs/troubleshooting/scheduling-failures.md \
i18n/zh/docusaurus-plugin-content-docs/current/troubleshooting/scheduling-failures.md
do
printf '\n### %s\n' "$f"
nl -ba "$f" | sed -n '1,155p'
done
printf '\n--- chart references and extraArgs definitions ---\n'
rg -n --hidden -S \
'scheduler\.extender\.extraArgs|extraArgs:|hami-charts/hami|version:' \
--glob '!node_modules' --glob '!dist' --glob '!build' .Repository: Project-HAMi/website Length of output: 36028 🏁 Script executed: #!/bin/bash
set -eu
for f in \
docs/troubleshooting/scheduling-failures.md \
i18n/zh/docusaurus-plugin-content-docs/current/troubleshooting/scheduling-failures.md \
docs/developers/profiling-scheduler.md \
i18n/zh/docusaurus-plugin-content-docs/current/developers/profiling-scheduler.md \
docs/installation/upgrade.md
do
printf '\n### %s\n' "$f"
sed -n '1,155p' "$f" | awk '{printf "%5d %s\n", NR, $0}'
done
printf '\n--- all repository definitions/usages of scheduler.extender.extraArgs ---\n'
rg -n -C 8 --hidden -S \
'scheduler\.extender\.extraArgs|extraArgs:' \
--glob '!node_modules' --glob '!dist' --glob '!build' .
printf '\n--- available Helm tooling ---\n'
command -v helm || trueRepository: Project-HAMi/website Length of output: 50378 🌐 Web query:
💡 Result: When using helm upgrade with --reuse-values, the behavior regarding precedence and merging is defined by how Helm handles existing versus new values [1][2][3]. Precedence and Merging Behavior 1. --reuse-values takes the computed values from the previous release, rather than the default values.yaml from the new chart [3][4]. 2. Any values provided via --set, --set-json, --values, or other override flags are then merged into these existing values [1][2][5]. 3. In this merge, the new values from your command-line flags take precedence over the previously stored values [1][2]. Array Handling with --set-json When using --set-json or --set to override arrays, it is important to understand that Helm treats arrays as single entities during the merge process [6]. Unlike maps (which are merged key-by-key), arrays are typically overwritten entirely by the new value provided [6]. If you provide an array via --set-json, that array will replace the entire array currently stored in the release values [6]. It will not perform a partial merge or append items to an existing array unless you explicitly include the original items in your new JSON input [6]. Summary of Precedence - New overrides (--set, --set-json, --values) always take priority over the values reused from the previous release [1][2]. - When multiple override flags are used in the same command, the right-most (last) flag specified takes precedence [2]. - Because --reuse-values explicitly excludes the new chart's default values.yaml, any changes to default values in a new chart version will be ignored unless you explicitly apply those values via a -f or --set flag [3][4]. Citations:
🏁 Script executed: #!/bin/bash
set -eu
python3 - <<'PY'
import json
import re
from pathlib import Path
files = [
Path("docs/troubleshooting/scheduling-failures.md"),
Path("i18n/zh/docusaurus-plugin-content-docs/current/troubleshooting/scheduling-failures.md"),
]
found = []
for path in files:
text = path.read_text()
for match in re.finditer(
r"helm upgrade hami hami-charts/hami \\\n"
r"\s+--namespace kube-system \\\n"
r"\s+--reuse-values \\\n"
r"\s+--set-json 'scheduler\.extender\.extraArgs=(\[[^']+\])'",
text,
):
args = json.loads(match.group(1))
found.append((str(path), args, "--version" in match.group(0)))
assert len(found) == 4, found
assert {tuple(args) for _, args, _ in found} == {
("--debug", "-v=5"),
("--debug", "-v=4"),
}
assert all(not has_version for _, _, has_version in found)
for path, args, _ in found:
print(f"{path}: extraArgs={args}; chart_version_pinned=False")
PYRepository: Project-HAMi/website Length of output: 654 Pin the chart version and preserve the complete Without 📍 Affects 2 files
🤖 Prompt for AI AgentsSource: MCP tools |
||
| kubectl rollout status deploy/hami-scheduler -n kube-system | ||
| ``` | ||
|
|
||
| Re-create the Pod, then read the log again. Each rejected device now names itself: | ||
|
|
||
| ```plaintext | ||
| CardInsufficientMemory pod="default/gpu-pod" node="node-a" device="GPU-62b7408e-edb2-41d1-bc91-f46165c61130" device total memory=40960 device used memory=39000 request memory=8000 | ||
| ``` | ||
|
|
||
| `-v=5` is verbose in proportion to cluster size: a 10-node cluster with 8 GPUs per node emits up to 80 lines for a single failed Pod. Return to the default once you have the answer: | ||
|
|
||
| ```bash | ||
| helm upgrade hami hami-charts/hami \ | ||
| --namespace kube-system \ | ||
| --reuse-values \ | ||
| --set-json 'scheduler.extender.extraArgs=["--debug","-v=4"]' | ||
| ``` | ||
|
|
||
| ## Messages that carry no reason code | ||
|
|
||
| Some failures are reported before per-device filtering runs, so they never produce a reason code. | ||
|
|
||
| | Message | Meaning | | ||
| | --- | --- | | ||
| | `no available node, N nodes do not meet` | Every candidate node was rejected. The specific reasons are in the other `FilteringFailed` events on the same Pod, so do not stop reading at this one. | | ||
| | `no available node, all node scores do not meet` | Same situation, reported by older HAMi versions without per-reason breakdown. Fall back to the scheduler log. | | ||
| | `node unregistered` (log only, `-v=5`) | The node has no HAMi device registration. Either its device plugin is not running, or it genuinely has no supported accelerator. Check `kubectl get node <name> -o jsonpath='{.metadata.annotations}'` for `hami.io/node-*-register`. | | ||
| | `Device type not found` | The Pod requests a device type the scheduler was not built or configured to handle, for example an Ascend request on a scheduler started without `--enable-ascend=true`. | | ||
|
|
||
| :::note Why some reasons never reach the events | ||
|
|
||
| The aggregated events are built by parsing the `<n>/<m> <Code>` fractions out of each node's reason string. Reason codes reported bare, without a fraction (`NodeInsufficientDevice` is the notable one), are recorded against the node but do not become their own `FilteringFailed` event. If the events look thinner than the failure, read the scheduler log. | ||
|
|
||
| ::: | ||
|
|
||
| ## Putting it together | ||
|
|
||
| ```mermaid | ||
| %% title: Diagnosing a Pending HAMi Pod | ||
| flowchart TD | ||
| A["Pod stays Pending"] --> B{"FilteringFailed<br/>event present?"} | ||
| B -->|No| C["Pod never reached HAMi:<br/>check schedulerName<br/>and admission webhook"] | ||
| B -->|Yes| D["Read every FilteringFailed event<br/>one per reason code"] | ||
| D --> E{"Reason code<br/>recognised?"} | ||
| E -->|Yes| F["Look up the code<br/>in the tables above"] | ||
| E -->|No| G["Read NodeUnfitPod lines<br/>in the scheduler log"] | ||
| G --> H{"Need the<br/>failing device?"} | ||
| H -->|Yes| I["Raise extender to -v=5,<br/>reproduce, revert to -v=4"] | ||
| H -->|No| F | ||
| ``` | ||
|
|
||
| ## Related Pages | ||
|
|
||
| - [Troubleshooting](./troubleshooting.md): installation and runtime problems that are not scheduling decisions | ||
| - [Scheduler Event Log](../developers/scheduler-event-log.md): the design behind these events and logs | ||
| - [Scheduling Policy](../userguide/nvidia-device/scheduling-policy.md): node and GPU selection policies that change which cards are considered | ||
| - [FAQ](../faq/faq.md) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: Project-HAMi/website
Length of output: 15122
🏁 Script executed:
Repository: Project-HAMi/website
Length of output: 3039
Align the reason-code documentation with HAMi v2.9.0.
HAMi v2.9.0 defines 16 reason constants and does not define
CardMigTopologyInfeasible. Update the English and Chinese introductions to link to the v2.9.0 source and state 16 codes. Remove the unsupported row from both tables or move it to a matching HAMi version.🧰 Tools
🪛 LanguageTool
[grammar] ~12-~12: Ensure spelling is correct
Context: ...ommon/common.go` in the HAMi repository. The list below reflects HAMi v2.9.0. Ol...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
📍 Affects 2 files
docs/troubleshooting/scheduling-failures.md#L12-L12(this comment)docs/troubleshooting/scheduling-failures.md#L95-L96i18n/zh/docusaurus-plugin-content-docs/current/troubleshooting/scheduling-failures.md#L13-L13i18n/zh/docusaurus-plugin-content-docs/current/troubleshooting/scheduling-failures.md#L96-L97🤖 Prompt for AI Agents
Source: MCP tools