Speech to Text troubleshooting
This page lists the errors that file transcription and realtime sessions return, then the usual causes of a missing, inaccurate, or slow transcript. Each fix links to the page that covers the setting to change.
Many transcript problems have a setting that fixes them, such as custom vocabulary for names or diarization for speakers. Check the symptom tables before you change models or contact support.
Errors
Errors arrive in a different form in each mode. A file transcription request returns an HTTP error with a JSON body, for example:
{
"object": "error",
"message": "Word-level segments are not enabled for this model",
"type": "invalid_request_invalid_args",
"param": null,
"code": "3051",
"raw_status_code": 400
}A 422 validation error carries its explanation in message.detail, a list where each item has a msg field. A realtime session sends an event of type error on the open connection, with the explanation in error.message:
{
"type": "error",
"error": {
"message": "Session fields cannot be changed after audio has started.",
"code": 3051
}
}File transcription errors
These errors come from a field of the transcription request. Fix the field and send the request again:
| Error | Cause | Fix |
|---|---|---|
400 Invalid model: <model> | The model isn't a transcription model you can use. | Use voxtral-mini-transcribe-3 or voxtral-small-transcribe-3. See Choose your model. |
400 Word-level segments are not enabled for this model | timestamp_granularities=word. Timestamps are per segment only. | Use segment. See Timestamps. |
422 When diarize is set to True and streaming is disabled, the timestamp granularity must be set to ['segment'] | diarize=true without segment timestamps. | Add timestamp_granularities=segment. See Diarize speakers. |
422 Invalid language alpha2 code | language isn't a two-letter code. | Use a code from Languages, such as en or fr. See Pin the language. |
422 Speaker references require diarization | Speaker references without diarize=true. | Set diarize to true. See Name speakers with reference clips. |
400 turn_detection is only supported on the realtime transcription endpoint. | turn_detection in a file transcription request. | Use a realtime session. See Turn detection. |
400 maximum context length | The audio and the context_bias entries together are over the model's context. Nothing is cut: the request fails. | Shorten the context_bias list. See Limits and errors. |
| The model doesn't accept reference clips. | Use a model that supports them. See Name speakers with reference clips. |
Realtime session errors
A realtime session can fail at the connection, or send an error event after a session.update message. Match the message, then fix the session configuration:
| Error | Cause | Fix |
|---|---|---|
| HTTP 403 at the WebSocket handshake | The model in the connection URL isn't a realtime model you can use. | Use voxtral-mini-transcribe-realtime-3. See Realtime transcription. |
Session fields cannot be changed after audio has started. | A session.update sent after the first audio chunk. | Send the whole configuration in one session.update before any audio. To change it, open a new session. See Realtime transcription. |
target_streaming_delay_ms must be one of the trained values: ['80-1200', '2400'] (got <value>). | A streaming delay outside the accepted values. | Use a value from 80 to 1200, or 2400. See Realtime transcription. |
Diarization is not compatible with turn detection. | diarize and turn_detection in the same session. | Keep one of them. See Diarization and turn detection. |
Speaker references require diarization, set diarize=true. | speaker_references without diarize. | Set diarize to true. See Name speakers with reference clips. |
Message contains Expected start_threshold >= eager_end_threshold > end_threshold | The turn detection thresholds are out of order. | Keep start_threshold at least eager_end_threshold, itself above end_threshold. See Tune thresholds. |
Message contains Expected end_timeout_ms to be greater than or equal to min_silence_ms | end_timeout_ms is shorter than min_silence_ms. | Raise end_timeout_ms or lower min_silence_ms. See Tune thresholds. |
Message contains Extra inputs are not permitted | A field the session doesn't accept, such as a configuration name in turn_detection. | Remove the field. To use a configuration, send its values. See Common configurations. |
Message contains Invalid language alpha2 code | language isn't a two-letter code. | Use a code from Languages. |
No transcript or missing fields
When a request succeeds but part of the result is missing, the cause is usually a field you didn't set:
| Symptom | Mode | Cause | Fix |
|---|---|---|---|
segments is empty | File | Segment timestamps aren't requested. | Add timestamp_granularities=segment. See Timestamps. |
speaker_id is null on every segment | File | Diarization isn't on. | Set diarize to true. See Diarize speakers. |
No transcription.text.delta events | Realtime | With diarization on, text arrives in transcription.segment events instead. | Read the text from transcription.segment. See Read speaker labels. |
No turn.* events | Realtime | turn_detection isn't in the session configuration. | Add a turn_detection object to session.update. See Enable turn detection. |
| Realtime | The audio_format in session.update doesn't match the audio you send: encoding or sample rate. | Declare the encoding and sample rate of your audio. See Realtime transcription. | |
| Realtime | The client didn't send input_audio.end after the last audio chunk. | Send input_audio.end when the audio is over. See Realtime transcription. | |
text is empty | File | The recording has no speech, or a format the API can't read. | Check the file plays, and its format. See Audio formats. |
Wrong words
When the transcript is there but some words are wrong, find the kind of error in this table:
| Symptom | Cause | Fix |
|---|---|---|
| Names, brands, product names, or jargon come out misspelled | The model doesn't know the term, and writes what it hears. | List each term as a keyphrase in context_bias. See Bias with keyphrases and Custom vocabulary. |
A term is still wrong in realtime, with only a description of the recording in context_bias | Add the term as its own keyphrase. See Use it in realtime sessions. | |
| Words come out in the wrong language | Without language, the model detects the language of the recording, and the detection can be wrong. | Pin the language with language. See Pin the language. |
| The realtime transcript has too many errors | A short streaming delay gives the model less context before it writes each word. | Raise target_streaming_delay_ms, at the cost of later text. See Realtime transcription and Latency. |
Speaker labels
Speaker labels raise their own questions. For what labels mean, see Speakers and diarization.
| Symptom | Cause | Fix |
|---|---|---|
A speaker you sent a reference clip for shows a generic label, such as speaker_3 | The clip doesn't match the voice in the recording, for example a different person who sounds alike. | Use a clip of the same person. See Name speakers with reference clips. |
| The same person has a different label in two recordings | Labels only hold within one transcript or session. | Name the speaker with a reference clip in each request. See Name speakers with reference clips. |
| Overlapping speech is not supported in this version. | Two people speak at the same time. | See Overlapping segments. |
Slow results
When the transcript is right but arrives too late, the setting to change depends on what the user waits for:
| Symptom | Mode | Cause | Fix |
|---|---|---|---|
| Realtime text appears too long after the words are spoken | Realtime | The streaming delay is long. | Lower target_streaming_delay_ms, at the cost of accuracy. See Realtime transcription and Latency. |
| Users wait for the whole transcript of a long file | File | The response arrives when the whole file is transcribed. | Stream the response to show the text as it comes. The total time stays the same. See Stream the response. |
| An agent answers long after the user stops speaking | Realtime | Turn detection waits for a minimum silence before it ends the turn. | Lower min_silence_ms, or start from the Aggressive configuration. Turns then end sooner, with more cut-offs. See Common configurations. |
Turn detection
Each turn detection symptom has one setting to move. Change one at a time, and test with recordings of your real users:
| Symptom | Fix |
|---|---|
| The turn ends while the user is still speaking, during a pause | Lower end_threshold, or increase min_silence_ms. The reply comes later. |
| The turn takes too long to end after a long pause | Decrease end_timeout_ms to cap the wait. |
| Turns start on background noise | Raise start_threshold. |
Too many turn.eager_end events | Lower eager_end_threshold. A turn.eager_end followed by turn.resume at a pause between sentences is expected. |
The last words of a turn arrive after turn.end | Keep adding text to the turn after turn.end. See The last words arrive after the turn event. |
For every setting, its default, and what it does, see Tune thresholds. For the trade-off between replying sooner and cutting people off, see Turns and turn-taking.