Developers who search for "Midjourney API errors" usually cannot find an official error-code table. Midjourney does not provide a public general-purpose API, so what you call is mostly a third-party wrapper or relay gateway, and the status codes, error fields, and retry rules are defined by the provider. The same 401 can mean different things on two platforms.

This article groups common failures by HTTP semantics and task lifecycle, then gives a troubleshooting order, retry and idempotency patterns, and a ticket checklist. Interfaces, error codes, and billing are governed by the provider's documentation.

Note: Midjourney is a trademark of Midjourney, Inc.; Discord is a trademark of Discord Inc. The third-party wrappers and relay services discussed here have no affiliation with those companies. Interfaces, error codes, and billing are governed by the provider's documentation.

1. First locate the layer where the error occurs

A call passes through five layers: client and network, gateway authentication, upstream account pool, generation task, and result storage and CDN. Failures at different layers look different:

Symptom Likely layer First step
All endpoints fail Client, network, DNS, proxy Change networks or reproduce with a minimal request
Only Midjourney fails Channel or upstream account pool Check the provider status page and other models
4xx at submission Authentication, parameters, rate limiting Check the request against the error code
Submission succeeds but the task fails Generation, moderation, upstream account Read the task error field
Task succeeds but the image will not open Result link, CDN, download Check link validity and retry the download

When troubleshooting, answer three questions first: is everything failing or only some requests? Did submission fail or did the task fail? Is it consistently reproducible or does it appear at peak times? These three answers can cut the search space in half.

2. 401 and 403: authentication, permission, and account status

401 means the identity was not recognized. Common causes include a missing or misspelled header, a key with extra whitespace or one that has been rotated, using a web cookie or temporary token as an API key, a wrong base URL, or clock skew that invalidates a signature.

403 means the identity was recognized but access is not permitted. Common causes include the key not being enabled for the model, an IP outside the allowlist, regional restrictions, an expired plan, an account under risk controls, or insufficient workspace permission.

Handling order:

  1. Reproduce with a minimal request that keeps only the authentication header and required parameters.
  2. Check the header name and prefix against the documentation, including whether there is a space after Bearer.
  3. In the console, confirm key status, model permission, balance, and expiry.
  4. Try a newly created test key; if 403 persists, ask the provider about IP, region, and account-pool status.

Do not put keys in front-end code or public repositories. When a 401 appears, suspect configuration first and do not retry in a loop; retries will not turn a wrong key into a correct one.

3. 429: rate limits, concurrency, and quota

429 is broader than many people think. It may mean the per-minute request limit is exceeded, the concurrent task limit is exceeded, the daily quota is used up, the account pool temporarily has no available account, or the upstream is queuing. Each cause requires a different response.

Check the response headers and error body first: if Retry-After is present, wait as instructed; if the message mentions quota or balance, it is usually a quota issue; if it mentions concurrency or queue, it is usually a concurrency issue; if all keys return 429 at the same time, the provider's account pool may be strained.

Ways to respond:

  • Add a client-side queue and limit concurrency; do not saturate the endpoint instantly.
  • Use exponential backoff with jitter so clients do not all retry at the same moment.
  • Distinguish "recovers after a wait" from "requires a top-up or a quota increase."
  • Record the model, time window, and request volume for 429s to judge whether the cause is your own traffic or upstream capacity.

429 is not solved by trying a few more times; blind retries lengthen the queue and may extend a ban.

4. Prompt rejected: moderation and parameter errors

A "prompt rejected" response has two kinds of causes. The first is content moderation: violence, sexual content, minors, real celebrities, copyrighted characters, trademarks, and political figures may all trigger it. The second is a parameter error: an unsupported aspect ratio, a nonexistent model version, an overly long prompt, or a reference-image URL that cannot be accessed or has an unsupported format.

Neither kind should be retried unchanged. For moderation rejections, adjust the material and wording; do not repeatedly try to bypass the filter with synonyms, split characters, or vague descriptions. For parameter errors, correct the fields against the documentation. Record rejected prompts, model versions, and response bodies, and turn them into team blocklists and validation rules.

Also distinguish "rejected" from "failed": the former usually happens before generation, while the latter may already have incurred a charge. The provider's rules govern.

5. Task failure, timeout, and result expiry

Task failures can come from upstream internal errors, account anomalies, invalid parameters, reference-image download failures, interrupted moderation, and queue timeouts. Read the error field instead of only looking at "failed."

Timeouts fall into three types: a client read timeout, where the request may already have reached the server; a submission timeout, where the task may have been created but the response did not return; and a polling timeout, where the task is still running but the waiting window has ended.

The most dangerous pattern is resubmitting immediately after a submission timeout, because the original task may already exist, resulting in duplicate charges. The correct approach: include an idempotency key or business request number at submission; after a timeout, query the most recent tasks by request number first; retry only after confirming that no task exists. If the provider does not support idempotency keys, implement a deduplication window in your task table.

Result expiry is another category. A successful response often returns a temporary URL valid from minutes to days, and it should not be stored as the asset address. Persist the image to object storage immediately after success, and keep only your own storage path and task ID in the database.

6. Download failures: 403, 404, and truncated files

A download failure does not necessarily mean generation failed. Common cases include a signed URL expiring and returning 403; results being cleaned up and returning 404; a proxy or network interruption resetting the connection; saving an HTML error page as an image; and a file that is only half downloaded.

Design downloads separately: validate Content-Type and file size; write to a temporary file first and then rename atomically; retry 5xx and network errors; for 403 and 404, do not retry generation but check task status to confirm whether the result still exists. If the provider offers multiple result addresses, prepare a backup domain or transfer channel.

7. Retry and idempotency: do not let failures become duplicate charges

The principle of retry is classification, not a uniform loop. For 401, 403, 400, 422, and moderation rejections, do not retry until the configuration or prompt is fixed; for 429, wait according to Retry-After; for 5xx, connection resets, and read timeouts, retry with backoff; for submission timeouts, query tasks first and then decide.

import random
import time
import requests

RETRYABLE = {429, 500, 502, 503, 504}

def post_with_retry(url, headers, payload, request_id, max_attempts=4):
    for attempt in range(1, max_attempts + 1):
        try:
            resp = requests.post(
                url,
                headers={**headers, "Idempotency-Key": request_id},
                json=payload,
                timeout=(10, 60),
            )
        except (requests.Timeout, requests.ConnectionError):
            if attempt == max_attempts:
                raise
            time.sleep(min(2 ** attempt + random.random(), 30))
            continue

        if resp.status_code in RETRYABLE:
            retry_after = resp.headers.get("Retry-After", "")
            wait = int(retry_after) if retry_after.isdigit() else 2 ** attempt
            time.sleep(min(wait + random.random(), 60))
            continue

        if resp.status_code >= 400:
            raise RuntimeError(f"{resp.status_code}: {resp.text[:200]}")
        return resp.json()

    raise RuntimeError("retry budget exhausted")

The Idempotency-Key in the example is only a common convention; whether it is supported and what the field is called depend on the provider's documentation. Without an idempotency key, a business request number plus deduplication in the task table achieves the same goal.

8. Checklist before filing a ticket

  1. Record the time, time zone, and duration of the incident.
  2. Include the request ID, task ID, and business order number.
  3. State the endpoint, model name, and API version.
  4. Include the full HTTP status code and response body; redact keys and personal information.
  5. Describe request parameters, the number of reference images, and the aspect ratio; do not just write "generation failed."
  6. Record retry count, intervals, network environment, and egress region.
  7. Provide minimal reproduction steps and the result of switching models with the same parameters.
  8. State the impact: how many tasks failed and whether online delivery is affected.

The most useful information in a ticket is the specific model, region, time window, parameters, and three request IDs, not "the API does not work."

9. Monitoring and prevention

Turn errors into metrics: count 401, 403, 429, 5xx, failed tasks, timeouts, and download failures by model; record P95 latency; reconcile daily whether failed tasks were billed. Set threshold alerts for 429s, task failure rate, and download failure rate instead of waiting for complaints.

Everyday prevention: split keys by environment and project, set quota caps on test keys, limit concurrency, and set a maximum retry count and dead-letter queue for each task type. When using a third-party wrapper, confirm its status page, response times, and shutdown plan; do not put all traffic on a channel without an SLA.

FAQ

What if 401 persists after changing the key?

First confirm the new key is active and has model permission, then check the header prefix, base URL, and system time. If other models work, the problem may be in the upstream account pool.

Does 429 mean insufficient balance?

Not necessarily. 429 may indicate request rate, concurrency, quota, or account-pool capacity. Check the response headers and error body first; only the words quota or balance strongly suggest a credit issue.

Can I resubmit directly after a task timeout?

It is not recommended. A submission timeout does not mean the task was not created, and resubmitting directly may cause duplicate charges. Query by request number or task ID first, and retry only after confirming that no task exists; include an idempotency key at submission if possible.

It depends on whether the provider retains results. Check task status first; if the result has been cleaned up, you usually have to regenerate. In production, persist results immediately after success to avoid depending on temporary links.

Will Midjourney officially handle errors from third-party interfaces?

No. Third-party wrappers have no affiliation with Midjourney, and the provider should investigate their errors; Midjourney also has no public API support channel.

Next steps

Classify errors into five groups first: authentication, rate limiting, content, task, and download. Then decide which should be retried and which should trigger an alert. If you need a unified entry point, create a key in ZSQH AI Gateway and confirm models and billing on the model pricing page.

Related reading: