Skip to content

Troubleshooting

Biowilko edited this page Aug 5, 2026 · 7 revisions

Troubleshooting

squarepeg raises a specific error type for every failure condition it detects, each carrying a fixed process exit code — see CLI Reference → Exit codes for the summary. This page covers what triggers each one and what to do about it.

Usage errors (exit code 2)

Situation Message tells you
Unsupported docker flag (--network, --gpus, -p, ...) The flag name, why it can't work on a remote cluster, and the config-passthrough equivalent if one exists — see the full table.
Malformed -e/-v/quantity value The offending token and the accepted forms.
-e KEY (bare, no =) but KEY isn't set in your local shell Which variable was missing.
-v /host/path:/container/path (host bind mount) without opting in Points at a config-defined PVC-backed volume, or allow_host_path_mounts: true.
--rm combined with --keep These are mutually exclusive.
--name isn't a valid RFC1123 label What the valid format is (lowercase alphanumeric + -, ≤63 chars).
A leading-dash token where the image name should be Names the token, explains it looks like a flag that landed before the image position.

Config errors (exit code 2)

Situation Message tells you
--config PATH / a $SQUAREPEG_CONFIG entry doesn't exist The exact path, and which source named it (--config foo.yaml vs $SQUAREPEG_CONFIG). The default location (~/.config/squarepeg/config.yaml) is the one exception — silently skipped if absent, since it's never explicitly requested.
Malformed YAML The file path and line number.
Unknown top-level config key (e.g. namesapce:) The key name and the exact file it came from.
Unknown --profile NAME Every profile name found across all merged config layers.
${VAR} reference to an unset environment variable The variable name, the exact key path (e.g. kubernetes.spec.imagePullSecrets[0].name), the source file, and a reminder that ${VAR:-default} exists — see Environment Variable Interpolation.
Malformed ${...} syntax (${}, ${1BAD}, unterminated ${VAR) The malformed token itself.
A config value squarepeg needs as an int/bool doesn't coerce (e.g. timeout: "soon") The key name and the value it couldn't parse.
volumes.NAME.mount_path isn't an absolute path The volume name, the source file, and the value it got instead.
volumes.NAME.read_only doesn't coerce to a bool Same as the general int/bool coercion case above, scoped to that volume's key.

Runner errors (exit code 125)

These mean squarepeg itself couldn't get the container to a known-good completed state — as distinct from the container running and exiting with its own non-zero code, which is reported verbatim instead.

Situation What happens
No kubeconfig found ($KUBECONFIG and ~/.kube/config both fail) Names the paths that were searched.
Unknown --context NAME Names the context that wasn't found in your kubeconfig.
Image pull failure (ImagePullBackOff, ErrImagePull, InvalidImageName, ...) Fails fast — doesn't wait out the full --timeout. Names the specific reason and message from the container's waiting state.
Container never starts within --timeout Reports the last known phase, plus any relevant Kubernetes events (scheduling failures, unbound volumes, etc.), then cleans up (unless --keep).
Container terminates but its exit code can't be read (evicted, deleted mid-run) Falls back to 125, matching docker run's own convention for "the runner failed" rather than fabricating a container exit code.

Kubernetes API errors (also exit 125, via ApiError)

HTTP status Hint squarepeg adds
401 "authentication failed; try kubectl get pods to check your credentials"
403 "permission denied; check with kubectl auth can-i create pods"
404 "not found; check the namespace exists"
409 "already exists; omit --name, or clean up a --keep'd previous run"
422 "the apiserver rejected the manifest; run with --dry-run to inspect it" — the most common symptom of a typo in kubernetes/job passthrough config, since that section is otherwise unvalidated by squarepeg

Interrupt (exit code 130)

Ctrl+C (or SIGTERM) during a run. See Execution Lifecycle → Interrupt handling for the two-stage behaviour — the first press cleans up and exits 130; a second press abandons the resource running instead.

General debugging tips

Symptom Try
"Why is my namespace/resource-size/whatever what it is?" squarepeg config show — prints every config file that was loaded, in merge order, plus the fully resolved (post-interpolation) result.
"Is my config producing the manifest I expect?" squarepeg run --dry-run ... — renders the exact manifest without touching the cluster at all.
A run seems to hang with no output Check stderr — squarepeg's own progress/event messages go there, separately from container stdout. If genuinely stuck past --timeout, it will time out and report the last known phase.
A container that reads stdin hangs after -t This is the documented tty implying stdin hazard — see Docker Compatibility → Interactive mode. Real stdin forwarding isn't implemented; avoid -t for containers that block on input.
"Why is this volume mounted — I never passed -v?" A config layer declared it as an auto-mount (volumes.NAME.mount_path) — see Configuration → Volumes. squarepeg config show will show you exactly which volumes.NAME entries have a mount_path set, and which config file set it.

Clone this wiki locally