> For the complete documentation index, see [llms.txt](/llms.txt)

# Runtime diagnostics

## Runtime diagnostics (raised by your generated SDK)

One code is different from every other on this page: it is emitted **into** your SDK and raised by
your own application at call time, not by `glotto` while generating. If you are looking for it in
`glotto generate` output you will not find it there — it appears in your application's logs or as an
exception at the call site.

| Code | Meaning |
| --- | --- |
| `GLOTTO_RESTRICTED_HEADER` | You passed a per-call header whose name the SDK's HTTP transport controls, so the SDK cannot send your value. The message names the header. Rather than dropping it silently — leaving you to discover from a packet capture that it never went out — the SDK refuses the call before any request is sent, so it has no server-side effect. |

**Which names are refused depends on the language**, because the transports genuinely differ and we
would rather not take a capability away from one SDK to match another's limitation:

| SDK | Refused | Sent normally |
| --- | --- | --- |
| Java, Kotlin (JVM) | `Content-Length`, `Host`, `Connection`, `Upgrade`, `Expect` | — |
| Go | `Content-Length`, `Host` | `Connection`, `Upgrade`, `Expect` |
| All other languages | — | all of the above |

The Java and Kotlin list is `java.net.http`'s own restricted set. That JDK exposes a
`jdk.httpclient.allowRestrictedHeaders` system property which can re-enable individual names; the
generated SDK deliberately does **not** consult it, because an SDK whose accepted headers changed
with a JVM flag would be harder to reason about than one that is consistently strict.

**Setting one of these headers is usually unnecessary.** `Content-Length` is computed from the body
you pass; `Host` follows from your configured base URL. If you need to reach a different host,
change the client's base URL rather than the header.

You can also see this code at **generation** time. If your spec declares one of these names as a
required header parameter, or sets one as an `auto_populate` constant, generation refuses instead —
emitting an SDK whose every call throws would not be something a caller could fix.
