# `internal_error`: Internal error

> HTTP 500. Something failed inside Commune. Retry with backoff, reusing the same `Idempotency-Key` for a write, and quote the request id if it persists.

The request was fine and Commune failed to serve it. For an unexpected failure the message is deliberately generic, because the underlying error can name internal details; the details are logged against the request id.

A few failures have their own message because they tell you something useful: whether the change was made, and that retrying is safe. They come from the safeguards the API refuses to skip. A read of subscriber email addresses is written to an audit log before it is returned. A write's `Idempotency-Key` is recorded before the change is made. A moderation change is attributed to the credential that made it.

Always keep `request_id` (it is also in the `Commune-Request-Id` response header). It is what lets the failure be found.

## Why it happens, and how to fix it

### 1. An unexpected failure

Something went wrong that Commune did not anticipate. The message reads "Something went wrong inside Commune."

**Fix:** Retry with exponential backoff, a few times. For a write, reuse the same `Idempotency-Key`, so that if the first attempt did go through you get its answer instead of a second change. If it keeps failing, contact Commune with the `request_id`.

### 2. A subscriber read could not be recorded

Reads that return email addresses (subscriber lists, a single subscriber, insights and events) are logged before they are served, and a read that cannot be logged is not returned. Nothing was returned.

**Fix:** Retry the read. Quote the `request_id` if it keeps failing.

### 3. The Idempotency-Key could not be recorded

A write's key is stored before the change is made, so that a retry cannot make it twice. When it cannot be stored the write is refused, and **the change was not made**.

**Fix:** Retry with the same `Idempotency-Key`.

### 4. A moderation change could not be attributed

Publishing a thread, tagging or untagging subscribers, deleting a tag and revoking a key are recorded against the credential that did them. When that record fails, the answer is a `500` even though **the change was made**.

**Fix:** Retry with the same `Idempotency-Key`: these operations land in the same state either way, and the retry writes the missing record. Within the first 60 seconds a retry answers `409` with `Retry-After`; wait and retry again.

### 5. The rate limit state could not be read

`GET /rate-limit` could not read the current budgets. Other operations are unaffected.

**Fix:** Retry the call, or read the `RateLimit-*` headers on any other response instead.

## Retrying

Usually yes: retry with backoff, reusing the same `Idempotency-Key` for a write so the change cannot happen twice.

## Headers

- `Commune-Request-Id`: The same value as `request_id` in the body. Quote it when reporting the failure.

## Example response

```json
{
  "error": {
    "code": "internal_error",
    "message": "Something went wrong inside Commune. The request can be retried; quote the request id if it keeps failing.",
    "request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
    "docs_url": "https://usecommune.dev/errors/internal_error"
  }
}
```

Often confused with: [`service_unavailable`](https://usecommune.dev/errors/service_unavailable.md), [`conflict`](https://usecommune.dev/errors/conflict.md).
