> ## Documentation Index
> Fetch the complete documentation index at: https://assemblyai.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshoot Common Errors

AssemblyAI's API always returns a response even when there is an error. This guide is designed to help you navigate and resolve common issues when implementing AssemblyAI.

## Understanding Errors with AssemblyAI

There are primarily two types of errors you might encounter when working with AssemblyAI:

* errors that occur when requesting a transcription (immediate HTTP `4xx` / `5xx`, message in the `error` field of the JSON body)
* errors that occur while the transcription is processing (the submit call returns `200`, but a later `GET /v2/transcript/{id}` shows `status: error` with the message in the `error` field)

The first category includes issues such as authentication errors, invalid request parameters, or server-related errors, which are typically flagged immediately when you attempt to initiate a request.

The second category, failed transcription jobs, pertains to errors that occur during the transcription process itself. These might be due to issues with the audio file, unsupported languages, or internal errors on our end.

## Handling Errors with AssemblyAI

### Error handling with AssemblyAI's SDKs (Recommended)

When using any of our SDKs, both types of errors are surfaced via the error key in a transcript object. For example in Python:

```python theme={null}
if transcript.status == aai.TranscriptStatus.error:
    print(transcript.error)
```

### Error handling with HTTPS requests

For errors when making a request for a transcription, you will have to check the status code that we respond with. For errors that occur during the transcription process, you will need to access the "error" key in the JSON response. For other HTTP errors you can print the information from the response object. Here is an example you can use:

```python theme={null}
if response.status_code != 200:
    try:
        print(response.json()['error'])
    except Exception:
        print(response.status_code, response.text, response.url)
```

## Common errors when making a request for a transcription

Unless otherwise noted, these errors are returned from `POST /v2/transcript` with the message in the `error` field of the JSON body.

#### Missing `audio_url`

```json theme={null}
# Status code: 400
{
"error": "Transcript creation error, audio_url not found"
}
```

This error occurs when the request body does not include the required `audio_url` field.

* **Solution**: Include an `audio_url` field that points to a publicly accessible audio file or to a URL returned by the [Upload endpoint](/api-reference/files/upload).

#### Unsupported language code

```json theme={null}
# Status code: 400
{
"error": "Language code <code> is not supported. See https://www.assemblyai.com/docs/concepts/supported-languages."
}
```

The `language_code` value you submitted isn't recognized.

* **Solution**: Check the [Supported languages](/pre-recorded-audio/supported-languages) page and submit a supported language code. You can also enable [Automatic Language Detection](/pre-recorded-audio/language-detection) instead of setting `language_code` manually.

#### Invalid `speech_models` value

```json theme={null}
# Status code: 400
{
"error": "\"speech_models\" must be a non-empty list containing one or more of: \"universal-3-pro\", \"universal-2\""
}
```

The `speech_models` parameter must be a non-empty list of supported model names.

<Note>
  Accounts on a feature flag for dated `universal-3-5-pro` variants may see additional model names in the list.
</Note>

* **Solution**: Pass a non-empty list, for example `["universal-3-5-pro", "universal-2"]`. See [Select the speech model](/pre-recorded-audio/select-the-speech-model) for guidance.

#### Deprecated `speech_model` (singular) parameter on async `/v2/transcript`

```json theme={null}
# Status code: 400 — POST /v2/transcript
{
"error": "speech_model is deprecated. Use \"speech_models\" instead. See documentation: https://www.assemblyai.com/docs/pre-recorded-audio/select-the-speech-model"
}
```

On the async pre-recorded API, the singular `speech_model` field no longer selects a model. Submitting a current model name (`universal-2`, `universal-3-5-pro`, `slam-1`, `conformer-2`) returns this 400 deprecation. Submitting a legacy value (`best`, `nano`, `universal`) returns 200, but the value is silently ignored and the job runs the default model (currently `universal-2`). Only the plural `speech_models` field actually selects a model on async.

<Note>
  Newer accounts may receive a slightly different deprecation message, but it points to the same fix.
</Note>

<Warning>
  This entry applies to the async pre-recorded API (`POST /v2/transcript`) only. The Streaming API is a separate system that uses its own singular `speech_model` field with values like `universal-streaming-english` and `universal-3-5-pro` — see [Streaming model selection](/streaming/select-the-speech-model). Don't treat the singular `speech_model` field as universally deprecated.
</Warning>

* **Solution**: On async, replace `speech_model: "<name>"` with `speech_models: ["<name>"]`. See [Select the speech model](/pre-recorded-audio/select-the-speech-model).

#### `language_detection` conflicts with `language_code`

```json theme={null}
# Status code: 400
{
"error": "`language_detection` is not available when `language_code` is specified."
}
```

You cannot set both `language_detection: true` and a specific `language_code` in the same request.

<Note>
  The plural `language_codes` field returns a different (similarly worded) message.
</Note>

* **Solution**: Either remove `language_code` and let [Automatic Language Detection](/pre-recorded-audio/language-detection) pick the language, or remove `language_detection` and keep `language_code`.

#### Wrong-type validation (Boolean, etc.)

```json theme={null}
# Status code: 400
{
"error": "`punctuate` must be a Boolean"
}
```

This is a generic wrong-type validation message. The field name changes depending on which parameter was submitted with the wrong type — any Boolean parameter sent as a non-Boolean value will trigger an equivalent message.

* **Solution**: Send the parameter with the correct JSON type (`true`/`false` for Booleans, an integer for integer fields, a string for string fields, etc.).

#### Invalid `webhook_url`

```json theme={null}
# Status code: 400
{
"error": "Invalid `webhook_url`, `webhook_url` should start with http."
}
```

The `webhook_url` field must be a valid URL beginning with `http://` or `https://`.

* **Solution**: Submit a fully-qualified webhook URL. See [Webhooks](/pre-recorded-audio/webhooks) for details.

#### Missing `redact_pii_policies`

```json theme={null}
# Status code: 400
{
"error": "You must explicitly define 'redact_pii_policies'"
}
```

This error fires when [PII Redaction](/guardrails/redact-pii-from-transcripts) is enabled but `redact_pii_policies` is missing.

<Note>
  This only applies to accounts created after `redact_pii_policies` became required. Older accounts auto-fill defaults and do not error.
</Note>

* **Solution**: Provide an explicit list of policies, for example `"redact_pii_policies": ["person_name", "phone_number"]`. See [Redact PII](/guardrails/redact-pii-from-transcripts) for the full list of supported policy names.

#### Unsupported policy name in `redact_pii_policies`

```json theme={null}
# Status code: 400
{
"error": "Unsupported policy name in 'redact_pii_policies', supported policy names are [...]"
}
```

One of the values in `redact_pii_policies` isn't a recognized policy.

* **Solution**: Use only policies from the list in the error message and in the [Redact PII](/guardrails/redact-pii-from-transcripts) docs.

#### Invalid `redact_pii_audio_quality`

```json theme={null}
# Status code: 400
{
"error": "Invalid `redact_pii_audio_quality` value, choose 'mp3' or 'wav'"
}
```

`redact_pii_audio_quality` only accepts `"mp3"` or `"wav"`.

* **Solution**: Set `redact_pii_audio_quality` to `"mp3"` or `"wav"`.

#### Malformed JSON body

```json theme={null}
# Status code: 400
{
"error": "Error processing request, json data invalid"
}
```

The request body could not be parsed as JSON.

* **Solution**: Verify the body is valid JSON, the `Content-Type: application/json` header is set, and that no stray trailing commas, comments, or unescaped characters are present.

#### Models are not supported for a particular language

```json theme={null}
# Status code: 400
{
"error": "The following models are not available in this language: speaker_labels"
}
```

This error occurs when you set `language_code` explicitly and enable a feature that isn't supported for that language. The API validates feature compatibility upfront and rejects the request.

<Note>
  This error only applies when using `language_code`. If you use [Automatic Language Detection](/pre-recorded-audio/language-detection) instead, the request will complete successfully, but any unsupported features will be silently omitted from the response. See [Unsupported feature behavior](/pre-recorded-audio/supported-languages#unsupported-feature-behavior) for more details.
</Note>

* **Solution**: Check the [Supported languages](/pre-recorded-audio/supported-languages) page to verify which features are available for your language before submitting a request.

#### Insufficient Funds

```json theme={null}
# Status code: 400
{
"error": "Your current account balance is negative. Please top up to continue using the API."
}
```

**Solution**:

* **Auto-pay**: Enable auto-pay in your account settings to automatically add funds when your balance runs low.
* **Check Funds**: Regularly check your account balance to ensure you have sufficient funds for your transcription requests.
* **Add Funds**: If needed, add funds to your account to continue using our services without interruption.

#### Invalid API Token

```json theme={null}
# Status code: 401
{
"error": "Authentication error, API token missing/invalid."
}
```

An invalid API token will prevent you from making successful requests.

**Solution**:

* Double-check that the API token you're using matches exactly with the token shown in your dashboard. Even a small typo can lead to authentication errors.

#### Transcript ID not found

```json theme={null}
# Status code: 400
{
"error": "Transcript lookup error, transcript id not found"
}
```

**Solution**:

* **Verify the endpoint and method that you are using**: Check that you are making a `POST` request to `http://api.assemblyai.com/v2/transcript`or a `GET` request to `http://api.assemblyai.com/v2/transcript/{transcript_id}` and not `http://api.assemblyai.com/v2/transcript/`
* **Token Verification**: Double-check that the API token you're using matches exactly with the token used to make the original request.
* If you're using Postman, ensure that `Encode URL automatically` under Settings is **disabled**.

#### Server Errors

```json theme={null}
# Status code: 500
{
"error": "Internal server error. Please retry your request. If the error persists, please contact support@assemblyai.com for more information."
}
```

Server errors rarely happen but can occasionally occur on our side.

**Solution**:

* **Retries**: Implement retries in your code for when our server returns a 500 code response. See [Implement Retry Server Error Logic](/pre-recorded-audio/guides/retry-server-error) for a worked example.
* **Automatic Retries**: Enable automatic retries for your transcription jobs under [Account > Settings](https://www.assemblyai.com/dashboard/home) on your dashboard. This ensures that if a job fails due to a temporary server issue, it will automatically be retried.
* **Check our Status page** to verify that we are not currently undergoing an incident
* **Reach out to Support**: Remember to provide the transcript ID, audio file used, and parameters used in your request or the full JSON response in your message. You can also email [support@assemblyai.com](mailto:support@assemblyai.com) for help!

## Errors on export, sub-resource, and upload endpoints

#### Requesting captions, sentences, or paragraphs before the transcript completes

```json theme={null}
# Status code: 400 — GET /v2/transcript/{id}/srt (or /vtt, /sentences, /paragraphs)
{
"error": "This transcript has a status of '<status>'. Transcripts must have a status of 'completed' before requesting captions."
}
```

The export endpoints can only be called after the transcript reaches `status: completed`. On the `/sentences` and `/paragraphs` endpoints the word `captions` in the message is replaced with `sentences` or `paragraphs` respectively.

* **Solution**: Poll `GET /v2/transcript/{id}` (or use a webhook) and only request captions/sentences/paragraphs once `status` is `completed`.

#### `word-search` called without `words`

```json theme={null}
# Status code: 400 — GET /v2/transcript/{id}/word-search
{
"error": "`words` is a required query parameter"
}
```

The `/word-search` endpoint requires the `words` query parameter.

* **Solution**: Pass a comma-separated list of search terms, for example `?words=foo,bar`. See the [Word Search](/api-reference/transcripts/word-search) reference.

#### Redacted audio not available

```json theme={null}
# Status code: 400 — GET /v2/transcript/{id}/redacted-audio
{
"error": "A redacted audio file for this transcript ID doesn't exist. Try submitting the transcript again with`redact_pii_audio`set to`true`."
}
```

The redacted audio file is only generated when [PII Audio Redaction](/guardrails/redact-pii-from-transcripts) was enabled at submission time.

* **Solution**: Resubmit the audio with `redact_pii: true` and `redact_pii_audio: true`. Set `redact_pii_policies` and (optionally) `redact_pii_audio_quality` to control what is redacted and the output format.

#### Invalid subtitle format

```text theme={null}
# Status code: 404 — GET /v2/transcript/{id}/<invalid-subtitle-format>
404: Not Found
```

When you request an unsupported subtitle format (anything other than `srt` or `vtt`), the API returns an HTML 404 page. The response body is the literal string `404: Not Found` — **not** JSON.

<Warning>
  This is the only documented endpoint where a 404 does not come back as a JSON object with an `error` field. A "handled" 404 — for example, looking up an unknown transcript ID — still returns JSON in the usual shape.
</Warning>

* **Solution**: Use `srt` or `vtt`. See [Export SRT/VTT subtitles](/pre-recorded-audio/export-transcripts-as-srt-vtt-or-text).

#### Empty upload body

```text theme={null}
# Status code: 422 — POST /v2/upload
Upload failed, please try again. If you continue to have issues please reach out to support@assemblyai.com
```

Posting an empty body to `/v2/upload` returns a `422`. The response body is **plain text**, not JSON.

* **Solution**: Stream the file bytes as the request body. See the [Upload endpoint](/api-reference/files/upload) reference.

#### Out-of-range `limit` when listing transcripts

```json theme={null}
# Status code: 400 — GET /v2/transcript
{
"error": "'limit' must be greater than or equal to 1"
}
```

The `limit` query parameter on `GET /v2/transcript` must be `>= 1`.

* **Solution**: Send a positive integer for `limit`. See [List transcripts](/api-reference/transcripts/list).

## Common transcription processing errors

These errors come back from `GET /v2/transcript/{id}` after the submit call returned `200`. The transcript has `status: error` and the message is in the `error` field.

#### Audio File URL Errors

##### Attempting to transcribe webpages or non-audio URLs

```json theme={null}
{
  "status": "error",
  "audio_url": "https://www.youtube.com/watch?v=r8KTOBOMm0A",
  "error": "Transcoding failed. File type <mime> (<detail>) may be unsupported or an unexpected error occurred. See supported formats at https://www.assemblyai.com/docs/faq/what-audio-and-video-file-types-are-supported-by-your-api. If your file format is supported and you're still encountering this error, contact us at support@assemblyai.com.",
  ...
}
```

Our API requires a publicly accessible URL that points to an audio or video file. If the URL points to a webpage, an unsupported file type, or transcoding otherwise fails, this error is returned. To transcribe a YouTube video, [check out this Cookbook](/pre-recorded-audio/guides/transcribe_youtube_videos).

* **Solution**: Confirm the URL serves a [supported audio or video format](/faq/what-audio-and-video-file-types-are-supported-by-your-api). If the format is supported and you still see this error, contact [support@assemblyai.com](mailto:support@assemblyai.com).

##### No audio stream in the file

```json theme={null}
{
  "status": "error",
  "error": "No audio stream found in the file. File type is <mime> (<detail>)."
}
```

The file downloaded successfully but contains no audio stream (for example, an image, a PDF, or a video file whose audio track has been stripped).

* **Solution**: Verify the file actually contains audio (for example with `ffprobe`). Re-encode or replace the file before resubmitting.

##### File exceeds the 5.5 GB maximum

```json theme={null}
{
  "status": "error",
  "error": "<audio_url> length=<bytes> exceeds max_content_length=5500000000"
}
```

The file is larger than the 5.5 GB cap. The size is read from the `Content-Length` header before download, so this error fires almost immediately.

* **Solution**: Split the file into smaller chunks (e.g. with `ffmpeg`) or downsample/transcode before submitting. See [Are there any limits on file size or file duration?](/faq/are-there-any-limits-on-file-size-or-file-duration-for-files-submitted-to-the-api).

##### URL returns an empty body

```json theme={null}
{
  "status": "error",
  "error": "No content found at <url>. Please make sure the file exists and is not empty."
}
```

The URL was reachable but returned an empty response body.

* **Solution**: Confirm the file is actually present at the URL and the server returns a non-zero `Content-Length`. Re-upload the file if necessary.

##### Uploaded file not found / region mismatch

```json theme={null}
{
  "status": "error",
  "error": "File not found at <url>. Make sure the file was uploaded recently and that you're transcribing from the same region."
}
```

The URL returned by `POST /v2/upload` could not be resolved. This usually means the upload has been garbage-collected, or the upload was made to one region (e.g. US) and the transcript was submitted in another region (e.g. EU).

* **Solution**: Re-upload the file and submit the transcript using the same regional base URL. See [Do you offer servers in the EU?](/faq/do-you-offer-servers-in-the-eu) for the per-region endpoints.

##### Attempting to transcribe audio files that are not accessible

```json theme={null}
{
  "status": "error",
  "audio_url": "https://foo.bar",
  "error": "Download error, unable to download https://foo.bar. Please make sure the file exists and is accessible from the internet."
}
```

**Solution**:

* **Public Access**: Verify that the audio file URL is publicly accessible. Our servers cannot transcribe audio from private or restricted URLs.
* **Google Drive URLs**: For audio stored on Google Drive, consult our [Google Drive Transcription Cookbook](/pre-recorded-audio/guides/transcribing-google-drive-file) to correctly format your URLs for access.
* **Direct Upload**: Utilize the [AssemblyAI Upload endpoint](/api-reference/files/upload) to upload files directly from your device, eliminating the need for a public URL.
* **AWS S3 Pre-signed URLs**: [This Cookbook](/pre-recorded-audio/guides/transcribe_from_s3) shows you how to use pre-signed URLs for AWS S3 storage to provide secure, temporary access for transcription without making your files public.

<Note>
  **Time-limited URLs (presigned URLs, CDN tokens, etc.) must be fresh when you submit them.** URLs from services like AWS S3 presigned URLs, Azure Blob Storage SAS tokens, GCP signed URLs, and social media CDNs (e.g., TikTok, Instagram) expire after a set duration. If the URL expires before AssemblyAI downloads the file, the origin server returns a `403` or `404` and you will see this download error.

  To avoid this:

  1. Generate the time-limited URL immediately before submitting your transcription request — do not cache or store URLs for later use.
  2. Ensure the URL expiration window is long enough for the file to be downloaded (at least a few minutes).
  3. If you cannot control the URL lifetime, use the [Upload endpoint](/api-reference/files/upload) to upload the file directly to AssemblyAI instead.
</Note>

#### Audio File Errors

##### Attempting to transcribe audio files that are too short

```json theme={null}
{
  "status": "error",
  "audio_url": "https://foo.bar",
  "error": "Audio duration is too short."
}
```

The minimum audio duration for a file submitted to our API is 160ms.

**Solution**:

* **Add error handling for this error message**: When this error occurs, handle it safely by checking the error string and returning the error.
* **Add pre-submit checks for the duration of the audio file**: Prior to submitting a file for transcription, check the duration using a tool like soxi (part of the SoX package): `soxi -D audio.mp3`

#### Language Detection Errors

##### No spoken audio detected

```json theme={null}
{
  "status": "error",
  "error": "language_detection cannot be performed on files with no spoken audio."
}
```

[Automatic Language Detection](/pre-recorded-audio/language-detection) requires spoken audio to analyze. Files that are silent, music-only, or otherwise contain no speech can't be language-detected.

* **Solution**: Disable `language_detection` and set `language_code` explicitly for files where speech may be absent, or skip transcription for files that are known to be non-speech.

##### Detected language confidence below the threshold

```json theme={null}
{
  "status": "error",
  "error": "detected language '<code>', confidence <c>, is below the requested confidence threshold value of '<threshold>'"
}
```

This fires when `language_detection` is enabled and the detected language's confidence is below the `language_confidence_threshold` you set. **Erroring is the default behavior** when the threshold isn't met.

* **Solution**: Set `language_detection_options.on_low_language_confidence` to `fallback` to fall back to a language you specify instead of erroring. Alternatively, lower the `language_confidence_threshold`. See [Automatic Language Detection](/pre-recorded-audio/language-detection) for details.
