Troubleshooting
Find your symptom, or search this page for the exact error text you were given.
Quick index
Section titled “Quick index”| Symptom | Section |
|---|---|
distil: command not found after installing |
Install and sign in |
Not logged in or session expired |
Install and sign in |
The sign-in code expired before it was confirmed |
Install and sign in |
Sign-in was denied in the browser |
Install and sign in |
You are already logged in as <email> |
Install and sign in |
No flag registered for --output |
Using the CLI |
Cannot use --data with individual file options |
Using the CLI |
<value> is not a valid UUID |
Using the CLI |
--output json printed an error instead of an id |
Using the CLI |
| A status command exits 0 although the job failed | Using the CLI |
Insufficient credits for this operation |
Credits |
Required file not found: ... |
Uploads and validation |
Failed to parse YAML file: / Failed to parse JSON file: |
Uploads and validation |
No config found in <path> / No job description found in <path> |
Uploads and validation |
Only the following tasks are supported: [...] |
Uploads and validation |
| A row in the wrong shape, named by its index | Uploads and validation |
| A command exits 1 naming another command, or the API answers 410 | Old entities |
base.enable_thinking=true is not available for student model |
Uploads and validation |
Failed to upload file: ... |
Uploads and validation |
| A field in my rows disappeared | Uploads and validation |
| I changed one config field and other settings reverted | My config changes didn’t stick |
A job has been JOB_PENDING for a long time |
Jobs that don’t seem to be moving |
| A job failed and I need the cause | A job failed |
| Training ran out of memory | Out of memory |
Relabelling ... traces into the ... split needs that many distinct traces |
Relabeling |
| Traces from the endpoint are missing or few | Relabeling |
| Fewer relabeled rows than traces | Relabeling |
| The traces are gone after an expand | Relabeling |
Teacher evaluation scores the teacher against a test set, and this job has none |
Empty splits |
Finetuning needs a training set, and this job has none |
Empty splits |
| Training finished but there are no scores | Empty splits |
| Fewer generated rows than the target | Smoke runs and generated data |
| A smoke run’s scores are low | Smoke runs and generated data |
| Reasoning rows were dropped | Smoke runs and generated data |
| A model can’t be deployed | Deployments and endpoints |
Deployment is not ready |
Deployments and endpoints |
| A key is rejected right after linking it | Deployments and endpoints |
No inference endpoint named "<name>" |
Deployments and endpoints |
Every record says fallback |
Deployments and endpoints |
| I need to change an endpoint | Deployments and endpoints |
deployment_status is JOB_SUCCESS after a delete |
Deployments and endpoints |
| The model answers badly, but the scores were fine | Good scores, bad answers |
| A locally served model answers like the base model | Good scores, bad answers |
| Reasoning text in the answers | Good scores, bad answers |
| vLLM fails to start with the adapter | Good scores, bad answers |
Cannot use --all with --count |
Downloads |
No traces found for <name> |
Downloads |
| Only 1000 traces, or only today’s, came back | Downloads |
SLM is still training, SLM is waiting for compute resources to be provisioned, Dataset <id> is not ready. Its job status is … |
Downloads |
Not enough disk space to download the model |
Downloads |
| I lost an id or an endpoint name | I lost an id |
Install and sign in
Section titled “Install and sign in”distil: command not found after installing. The installer puts the binary in
~/.local/bin. Add that directory to your PATH and open a new shell. The CLI runs on Linux
(x86_64, arm64) and macOS (Intel, Apple Silicon); on Windows, run it inside WSL. See
Ways to use distil labs.
Not logged in or session expired. Run `distil auth` to authenticate or `distil signup` to create an account.
Run distil auth. If you have no account yet, run distil signup first.
The sign-in code expired before it was confirmed. Run `distil auth` to try again.
The code is valid for a few minutes. Run the command again and confirm the new code promptly. If the browser never opened, use the address the command printed: it works from any device, so on a remote shell, open it on your laptop or phone.
Sign-in was denied in the browser. Run `distil auth` to try again.
The request was declined on the confirmation page. Run the command again, and confirm only a code that matches the one in your terminal.
You are already logged in as <email>
Run distil logout first to sign in with another account.
See Account and authentication.
Using the CLI
Section titled “Using the CLI”No flag registered for --output
--output json exists on every command that reads, creates, deletes, links or downloads, but not
on auth, signup, logout, access-token, update, docs or skill, nor on the deprecated
commands. Nothing was done: drop the flag. See
Commands that accept –output json.
Cannot use --data with individual file options (...)
Pass either --data <dir> or the per-file flags (--train, --test, --config, …), not both.
With per-file flags, the message Missing required options: ... names the files still missing.
<value> is not a valid UUID
An entity id was mistyped or truncated. Copy it again from the output of the command that created
it, or recover it with list (I lost an id).
--output json printed an error instead of an id. With --output json, an error is printed
to stdout as {"error": "..."} and the command exits 1. Read the error rather than the id, and
check the exit code in scripts.
A status command exits 0 although the job failed. A status command that reaches the platform
exits 0 whatever the job did. Read the status field, not the exit code.
Credits
Section titled “Credits”Insufficient credits for this operation
Credits are counted per route: each kind of create has its own balance, so running out on one says nothing about the others. Check every balance:
distil credits-balance
Read the balance against your whole plan: N training runs need N training credits. --smoke
runs have their own routes. A route missing from the list is not metered, rather than empty.
slms_post starts at zero and needs a grant. The route table
and the starting balances are in
How the platform works. To get more, email
contact@distillabs.ai.
Check your training balance before generating data. A generation run with no training credit left produces data you can’t train on yet.
Uploads and validation
Section titled “Uploads and validation”The create commands check what they can before creating anything. Fix the cause and run the command again.
Required file not found: test.jsonl in input-dir
A file is missing from the directory. The required files per command are in
Supplying files. train.jsonl and test.jsonl can be
empty but must exist.
Failed to parse YAML file: <path>
Failed to parse JSON file: <path>
config.yaml or job_description.json isn’t valid YAML or JSON. This applies to --data
directories and to --config and --job-description overrides alike.
No config found in <path>. A config override has to be a complete YAML mapping; omit --config to inherit instead.
The override file is empty or isn’t a mapping. The same holds for No job description found in <path>. Leave the flag out to keep the parent’s file.
Only the following tasks are supported: ['question-answering', …]
The task classification is no longer supported. Use the task question-answering instead, with a mutator over the class labels.
The task tool-calling-closed-book is no longer supported. Use the task chat-completion (or chat-completion-agentic for multi-turn conversations with tool results) instead.
base.task must be one of question-answering, chat-completion or chat-completion-agentic
(Task selection). A config from an older project that names
classification or one of the tool-calling tasks is rejected with the replacement to use;
Migrating lists the changes to make.
1 validation error for JobInputParser
job_input.1.data.question-answering.train_dataset.0.messages
Field required [type=missing, input_value={'wrong': 'shape'}, input_type=dict]
A row is the wrong shape, named down to the row index. Check it against the row format. Common causes:
- Chat completion: a
role: "tool"message is only valid inchat-completion-agentic; rows carry nosystemmessage unlessbase.variable_system_promptis on;function.argumentsis a JSON object, not a string. - A row appears in both
train.jsonlandtest.jsonl.
The same section lists the other combinations a config is refused for: a reasoning teacher needs
teacher_temperature between 0.5 and 0.7, visual_task needs vision-capable models, and tools
restrict the students and teachers.
base.enable_thinking=true is not available for student model '<name>'
Only some students can be trained as reasoning models (Reasoning models).
Failed to upload file: <status>
A file didn’t reach storage while a create command was uploading it. Run the command again.
A field in my rows disappeared. Keys a row doesn’t define are dropped without an error. For
reasoning, the field is reasoning_content on the assistant message, not reasoning on the row.
My config changes didn’t stick
Section titled “My config changes didn’t stick”An override replaces config.yaml and job_description.json whole. Anything you leave out
reverts to the library default, not to the parent’s value, and nothing errors. A config with a
complete base but no synthgen section runs with train_generation_target: 10000 and no mutators,
whatever the parent set.
Read the parent’s config back, which is free, change one field, and send the whole file:
distil <group> download-metadata -d ./iter-2 <id>
# edit one field in ./iter-2/config.yaml
distil <group> create-from-<parent> --config ./iter-2/config.yaml <parent-id>
A config without base.task is refused with Invalid config: ... base.task Field required. To
check what a submission ran with, download its metadata and diff the two files.
An override changes the config and the job description only. Different data needs a new upload.
Keys such as tuning.train_eval_split appear in every config the platform returns but have no
effect (Config file).
Jobs that don’t seem to be moving
Section titled “Jobs that don’t seem to be moving”JOB_NOT_STARTED and JOB_PENDING mean the job was accepted and is waiting to be scheduled or
for capacity. Check the status with:
distil <group> status <id>
The status values are in Job status. Deployments report
deployment_status and endpoint_status instead of a status.
If a job stays pending, email contact@distillabs.ai with the entity id. There is no cancel command.
A job failed
Section titled “A job failed”Print the job’s log:
distil <group> logs <id>
Search the log for the first error, not the last one. A crash often ends with a second, unrelated
error: an out-of-memory failure can end with a pickling error thousands of characters after the
OutOfMemoryError that caused it.
A failed job produces no metrics. Fix the cause and submit again from the same parent. Some failed entities can’t return their config afterwards, so keep your own copy of what you submitted.
Out of memory
Section titled “Out of memory”Lower the batch size, then turn on memory-optimized training, then QLoRA, then drop the longest
training rows. Each costs more speed or quality than the one before. The settings, and what each
one spends, are in
Model training. A --smoke
training after each change checks memory before the full run.
Relabeling
Section titled “Relabeling”distil traces upload and distil dataset create check that the files are there and that the
config parses. Problems in the traces fail the first expand that reads them, and the job log names
the cause.
Relabelling 200 traces into the test split needs that many distinct traces, and the dataset has 120.
Lower trace_processing.num_test_relabelled to at most 120, or provide more traces.
The job relabels exactly the count the config asks for, counted after deduplication, and fails
with fewer. Lower num_test_relabelled or num_train_relabelled, or add traces. A
--smoke relabels 128 and is refused the same way below 128 traces. Count for both splits before
the first run: each expand removes the traces it used
(Building the test set).
Traces from the endpoint are missing or few. With
distil traces create-from-inference-endpoint, a call becomes available about 24 hours after it
was made. To use traces right away, download, convert and upload them instead
(Endpoint records to traces).
Fewer relabeled rows than traces. Filtering, relabeling, validation and the overlap check
against the other split each drop traces, and the job writes whatever survives, zero rows
included. Check, in this order: base.task against the shape of your traces (multi-turn
conversations need a chat completion task), observation_format against the trace file, and the
relevance filter against the job description. The job log counts each drop
(Relabeling).
The traces are gone after an expand. Every expand removes the traces it used, and a
generation run takes up to T + min(T, 1000) traces as context for a target of T. The parent
dataset still has them: a smoke’s output is a side branch, and the full run goes on the parent
(The expand operations).
Old entities
Section titled “Old entities”A command exits 1 naming another command, or the API answers 410. The entity is a seed dataset or a training dataset: download it and upload it as a dataset (Migrating old entities).
Empty splits
Section titled “Empty splits”train.jsonl and test.jsonl may be empty, but two stages need one of them populated
(Empty splits).
Teacher evaluation scores the teacher against a test set, and this job has none:
test.jsonl is empty. Provide test examples, or skip this stage.
The dataset’s test split is empty. Build the test set from the traces, or
upload a test.jsonl with them.
Finetuning needs a training set, and this job has none: train.jsonl is empty.
Generate synthetic data first, or provide training examples.
Build the train set first. It fills the training split.
Training finished but there are no scores. The test split is empty. Training produced a
model and skipped evaluation, so distil slm metrics returns null scores. The job did not fail.
Smoke runs and generated data
Section titled “Smoke runs and generated data”A smoke run’s scores are low. That is expected. A training smoke trains one epoch on the 128 longest training rows to check memory; its scores say nothing about the full run.
Fewer generated rows than the target. Validation dropped rows, most often for
length or format. Raise synthgen.validation_max_total_length if real examples are long, and
check the format rules in the job description. Ending a little above the target is normal:
generation runs in batches of generation_iteration_size.
Reasoning rows were dropped. Rows the reasoning backfill couldn’t complete, or that grew past
validation_max_total_length, are removed. A warning that tuning.max_completion_length is
below the longest training completion means raise it
(Reasoning models).
Deployments and endpoints
Section titled “Deployments and endpoints”A model can’t be deployed. A deployment serves the model’s LoRA adapter. A model trained with
a tuning.lora_r other than 8, 16, 32, 64, 128, 256, 320 or 512 has no adapter that can be
served. Train it again with a supported value.
Deployment is not ready
distil inference-endpoint create-from-deployment refuses until the deployment is serving. Poll
it, then create the endpoint:
distil deployment status <deployment-id>
A key is rejected right after linking it. A key change takes up to a minute to reach the
endpoint. Wait and retry. A key authenticates nothing until it is linked to the endpoint with
distil inference-endpoint link-api-key.
No inference endpoint named "<name>". Run `distil inference-endpoint list` to see what's available.
Every command takes the unique endpoint name the platform returned (support-yeOdAS), not the
prefix you chose (support).
Every record says fallback. The deployment behind the endpoint has stopped, and the
fallback answers every call. A hosted deployment is a session for trying your model: it stops
after six hours, or after one hour with no traffic, and it can’t be restarted. Create a new
deployment and a new endpoint in front of it, or email
contact@distillabs.ai for a permanent deployment.
I need to change an endpoint. An endpoint can’t be edited or deleted. A different fallback or
primary means a new endpoint, and your application moves its model string to the new name.
The deployment still says JOB_SUCCESS after distil deployment delete. That is expected.
endpoint_status reading stopped confirms it is down.
Good scores, bad answers
Section titled “Good scores, bad answers”The answers are worse than the scores promised. A hand-built chat completions request fails
quietly: the endpoint answers 200 and the quality drops. Each model ships with its own
model_client.py, which sends the request the model was evaluated with: the same sampling
settings and thinking on or off as in training, with the conversation you pass, system prompt first. An application that sends its own
requests must send a system prompt: the task_description from the job description, or, with
variable_system_prompt on, the system prompt it chooses for
that request. Download
the client and send a request through it:
distil slm download-metadata --destination ./model <slm-id>
uv run ./model/model_client.py --base-url https://inference.distillabs.ai/v1 \
--api-key <api-key> --model <unique-endpoint-name> --conversation '[{"role": "system", "content": "<system prompt>"}, {"role": "user", "content": "..."}]'
Check in the endpoint’s records that metadata.source is primary: a fallback answer came
from the fallback model. See distil labs inference.
Reasoning text in the answers. From a model trained with base.enable_thinking: true, that
is expected. From a model trained without it, the request was built by hand: use the client.
When serving locally, a thinking block at the start of content means the family’s
--reasoning-parser flag is missing.
A locally served model answers like the base model. The request named base instead of
model. vLLM serves the adapter under the name model and the untrained base model under
base. See Local deployment.
vLLM fails to start with the adapter. --max-lora-rank must be at least tuning.lora_r
from the model’s config.yaml (default 64). The Llama and Gemma base models are gated on
HuggingFace: accept the license on the model page and export HF_TOKEN.
Downloads
Section titled “Downloads”Cannot use --all with --count. --all downloads every trace; --count downloads that many
Pass one of them.
Only 1000 traces, or only today’s, came back. distil inference-endpoint download-traces
defaults to the last day and the newest 1000 records. Widen the window with
--from-start-time <date> and take every record in it with --all.
No traces found for <name> between <from> and <to>. Set --from-start-time to an earlier time to include older traces.
The endpoint recorded no calls in the time window, and no file was written.
SLM is still training
SLM is waiting for compute resources to be provisioned
Dataset <id> is not ready. Its job status is JOB_RUNNING.
The job hasn’t finished. Poll its status and download once it reports Success. The command
exits 1 and writes nothing. With JOB_FAILURE in that message the job failed and the dataset
has no files; read its logs.
Not enough disk space to download the model. Required: <size>, available: <size>
Free some space, or fetch only the client and config with distil slm download-metadata, which
is a few kilobytes.
slm download-predictions has no base model rows. It holds the trained model’s predictions
only. The base model’s scores are in distil slm metrics.
I lost an id
Section titled “I lost an id”Every entity records its parent, so nothing is lost for good. List a group’s entities:
distil <group> list
The command returns one object per entity, newest first, with id, created_at and the parent’s id under
its own key (dataset_id, slm_id), and a dataset with its operation and parent. list
carries no status, so
checking state costs one status call per id. A lost unique endpoint name is in
distil inference-endpoint list.
Still stuck
Section titled “Still stuck”Email contact@distillabs.ai with the entity id and the command you ran.