Skip to content

Troubleshooting

Common issues when integrating with Obstruo, with their causes and fixes.


401 Unauthorized

Symptom: every request returns HTTP 401.

Causes:

  1. Wrong API key - you're sending an OpenAI key instead of an ObstruoKey, or the key was copied incorrectly.
  2. Wrong base URL - you're pointing at api.openai.com instead of api.obstruo.ai/your-org/v1.
  3. Key deactivated - the ObstruoKey was deleted or disabled in the panel.
  4. Org slug mismatch - the slug in the URL doesn't match the org the key belongs to.

Fix: go to Keys → Obstruo keys and confirm the key is active. Check that your base_url is the ENDPOINT value shown in that same row.


The response echoes my own prompt back

Symptom: the request succeeds (HTTP 200), but the "assistant response" is just your own message repeated - possibly with placeholders like [EMAIL_ADDRESS] in it - and the response metadata shows obstruo.routing.audit_only: true.

Cause: the model name you sent doesn't resolve to any upstream target, so Obstruo processed the request in audit-only mode: it redacted and logged the request, but didn't call an LLM. This is intentional - an unconfigured model is a valid gateway mode, not an error. In this mode obstruo.redaction also carries the full detection detail (redacted_messages, entities, placeholders), which makes it a handy dry run for a redaction policy.

Typical reasons the model doesn't resolve:

  1. Logical model not created - you're passing model="obstruo-chat" but haven't created a logical model with that name (check for typos).
  2. Logical model has no backing models - the logical model exists but has no provider key + model targets configured.
  3. Provider model not allowed - the underlying model (e.g. gpt-4o) hasn't been added under Models → Models allowed.

Fix: go to Keys and confirm the logical model exists and has at least one backing model. Go to Models → Models allowed and confirm the underlying model is listed.

Note

If your ObstruoKey is deliberately set to Audit-only mode, this behaviour applies to every request on that key - see the Mode field in Quick Start.


Requests are being blocked (finish_reason: "content_filter")

Symptom: responses come back with finish_reason: "content_filter" and empty content.

Cause: an inbound guardrail rule matched the prompt.

Fix:

  1. Go to Enforce → Guardrails → Inbound and review which rules are active.
  2. Check the Observability → Audit log - find the blocked request and see which rule fired.
  3. If the block is a false positive, adjust the rule threshold or disable the rule.

Streaming responses have no obstruo key

Symptom: you're using stream: true and looking for response.model_extra["obstruo"] - it's missing.

Cause: this is expected. For streaming responses, Obstruo metadata travels on HTTP response headers, not in the body.

Fix: read the X-Obstruo-Pii-State header instead. Use create(stream=True) - the .stream() helper does not expose response headers:

stream = client.chat.completions.create(
    model="obstruo-chat",
    messages=[{"role": "user", "content": "Hello!"}],
    stream=True,
)
pii_state = stream.response.headers.get("x-obstruo-pii-state")
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

HTTP 429 - rate limit or budget exceeded

Symptom: requests fail with HTTP 429.

Cause: the ObstruoKey or project has a rate limit or monthly budget set, and you've hit it.

Fix:

  • Check the error message - it specifies which limit was hit and the current value.
  • Increase or remove the limit in Keys (per key) or Administration → Projects (per project).
  • If it's a plan quota, contact hello@obstruo.ai.

See Limits & Budgets for full details.


PII is not being redacted

Symptom: you expected PII to be replaced but the LLM is receiving the original values.

Causes:

  1. Redaction is disabled for this project - check Enforce → Redaction and confirm it's enabled.
  2. The entity type isn't covered - the default regex patterns cover common types (email, phone, credit card, SSN, IP, IBAN). Custom patterns or the NER layer may need to be enabled for other types.
  3. The NER layer is off - enable it under Enforce → Redaction → NER layer.

Fix: use the Test panel on the Redaction page to paste sample text and see exactly what would be detected before saving changes.


The audit log shows no requests

Symptom: you're making calls successfully but Observability → Audit log is empty.

Causes:

  1. Wrong project selected - the project picker in the top-right corner scopes all panel views. Make sure the project your ObstruoKey belongs to is selected.
  2. Short delay - audit events appear within a few seconds; refresh the page.

A model doesn't show up when creating a logical model

The backing-model list in the logical model dialog is built from each provider key's Allowed models, not directly from the model catalog. Adding a model under Models → Models allowed (and pricing it) is not enough by itself.

Work through the chain:

  1. Models → Models allowed - the model exists in the catalog, with the Provider field matching your provider key's API type exactly and the right kind (chat / embedding / audio).
  2. Connections → Provider keys → edit the key - the model is ticked under Allowed models. If the list there is empty, the catalog entry's provider name doesn't match the key's API type.
  3. Connections → Logical models - the (key, model) pair is now selectable.

Requests fail with "all targets failed" right after adding a model

The model name is sent to the provider verbatim. A name that doesn't exist upstream returns 404, which Obstruo treats as "this model isn't here" and fails over to the next target - with a single target the request fails.

If the message mentions "The SSL connection could not be established", the provider key's address is missing a scheme: a bare host:port/v1 defaults to https://, which a plain-HTTP server (local Ollama, vLLM) rejects. Set the address with an explicit http://.

Otherwise check the model identifier in Models → Models allowed against the provider's own list (for self-hosted Ollama: ollama list - the full name including the tag, e.g. SpeakLeash/bielik-7b-instruct-v0.1-gguf:latest). Use Test connection on the provider key to rule out credential and address problems.

Need more help?

Contact hello@obstruo.ai and include:

  • Your org slug
  • The error message and HTTP status code
  • The approximate time of the affected request