# Reported issues for AISIX AI Gateway

Pod holds 14 of 14 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.

Back to [AISIX AI Gateway](/mcp/aisix-ai-gateway).

## Most discussed

### Upstream TLS trust: no config surface for a private CA, and no verification override

## Description

Outbound TLS trust has no configuration surface. There is no `ssl_verify`-style switch and no way to point the gateway at a private CA bundle from config:

- no `tls` / `ca_file` / `verify` field in the `upstream:` config section, which otherwise carries the connection-layer settings (timeouts, keepalive, pool, retries);
- no TLS field on any resource in `schemas/resources/` — in particular `provider_key`, which is where an upstream endpoint (`api_base`) is declared;
-…

[Read the thread](https://github.com/api7/aisix/issues/860) · 2026-07-31 · closed · 2 comments

### /v1/completions emits an empty applied_guardrails while its chain does run

Found by the independent pre-merge audit of #1028.

`/v1/completions` resolves a guardrail chain (`crates/aisix-proxy/src/completions.rs`, `state.guardrail_index.resolve(&guardrail_ctx)`) and runs both the non-segment check and the segment pass over the prompt — but never snapshots `resolved_chain.applied()`, and `emit_usage_event` never sets `applied_guardrails`. The emitted event leaves the field empty.

Every sibling handler fills it: chat, messages, responses, embeddings, rerank, images,…

[Read the thread](https://github.com/api7/aisix/issues/1030) · 2026-08-22 · open · outside contributor · 1 comment

### bug: on /mcp the guardrail scan text and the mask surface are different texts — block, would_mask and mask disagree

## Summary

On `/mcp` the guardrail **scan** (which decides `block`, and which monitor mode
previews as `would_mask`) and the guardrail **rewrite** (which actually masks)
run over *different texts*, in three different shapes. So a rule can block
without ever masking, mask without ever being able to block, and preview as
would-mask while enforcement does nothing — with no error and no signal in
telemetry.

## The three texts

| what | text handed to the rules | source |
|---|---|---|
| input…

[Read the thread](https://github.com/api7/aisix/issues/1027) · 2026-08-22 · open · outside contributor · 1 comment

### bug: field-name-anchored guardrail rules never fire for action=block on the /mcp output hook

## Summary

On `/mcp`, a guardrail rule anchored on a JSON **field name** now works for
`action: mask` but silently never fires for `action: block` on the **output**
hook. Block is the stricter action, so the gap is fail-open.

## Why the two hooks differ

| surface | code | key visible to the rule |
|---|---|---|
| input scan (block) | `crates/aisix-proxy/src/mcp.rs` — `args.to_string()` | yes, compact `"version":"12.1"` |
| input + output mask | `crates/aisix-proxy/src/redact.rs` —…

[Read the thread](https://github.com/api7/aisix/issues/1026) · 2026-08-22 · closed · outside contributor · 1 comment

### files surface: the batch-input blob is scanned lossy but forwarded verbatim — same skip-vs-forward asymmetry class as #1016

Surfaced by the #1020 audit (LOW, pre-existing, out of #1016's `prompt`-field scope).

`/v1/files` (`jobs.rs`): `scan_input_blob` runs the guardrail scan over `String::from_utf8_lossy(&file_bytes)`, while `create_file` forwards the original bytes verbatim. The scan always runs (unlike the pre-#1020 prompt skip), but the same evasion argument applies: a keyword in a foreign encoding never appears in the lossy text, yet the original bytes still leave the boundary to the provider. A DLP block…

[Read the thread](https://github.com/api7/aisix/issues/1022) · 2026-08-21 · closed · 1 comment

### Harden MCP upstream transport: credentialed cleartext URLs and redirect policy

Surfaced by automated review on #875 (the finding anchors on new code, but the behavior is the long-standing shared bridge path used by both /mcp and /mcp/{server}).

Today `RmcpBridge::connect` accepts `http://` upstream URLs for credentialed MCP servers, and the underlying HTTP client follows redirects. reqwest strips `Authorization` on cross-origin redirects, but custom credential headers (e.g. an `api_key` auth header) are not in its sensitive-header set, so a compromised/misconfigured…

[Read the thread](https://github.com/api7/aisix/issues/879) · 2026-08-04 · closed · outside contributor · 1 comment

### bug: output guardrail error message echoes the matched forbidden literal back to caller

## Summary

When an output guardrail with `kind: "keyword"` and `hook_point: "output"` blocks an upstream response containing a forbidden literal, the gateway's caller-visible error message includes the matched literal verbatim — defeating the purpose of an output guardrail (which exists precisely to keep forbidden content from reaching the caller).

## Repro

E2E test attached: drafted as `tests/e2e/src/cases/guardrail-output-e2e.test.ts` (held back from #151 batch 2 PR pending this fix).…

[Read the thread](https://github.com/api7/aisix/issues/153) · 2026-05-09 · closed · 1 comment

### guardrails: scan batch input files per record, not as one lossy text blob

Single record for guardrail coverage on the files surface. The issues that led here stay closed; this is the one place the decision lives.

## Where it stands

Guardrails no longer apply to `/v1/files` at all — neither the upload nor the download, and neither does the refusal that was briefly built on top of them. Removed in #1121.

What still scans: the JSON request bodies of `/v1/batches` and `/v1/fine_tuning/jobs`. Those are structured requests the gateway understands, not user-uploaded…

[Read the thread](https://github.com/api7/aisix/issues/1120) · 2026-09-03 · open · outside contributor · 0 comments

## Most recent

### guardrails: thinking and reasoning content is out of scope by comment only — mask never redacts it, and scan coverage differs per route

Found while documenting the buffered-scan behaviour for #1103, and verified separately against `origin/main` @ `45f4c327`. This is **not** the parsing-boundary class #1103 tracks: these events are modelled and parsed. The text is deliberately not extracted.

**Masking never touches thinking or reasoning content, on any route or mode.** Four sites decide and all four omit it: `redact_anthropic_content` (`redact.rs:426-457`, `_ => {}` drops `thinking`), `redact_chat_response` (`redact.rs:697`),…

[Read the thread](https://github.com/api7/aisix/issues/1106) · 2026-09-02 · closed · outside contributor · 0 comments

### A stream aborted by the guardrail buffer cap reports guardrail_blocked with no policy named

Found by the independent pre-merge audit of #1028.

## The gap

When a streamed response exceeds a guardrail's `max_buffer_bytes` and the row is configured `on_buffer_exceeded: fail_closed`, the gateway refuses the request — but no chain member ever returned a verdict, because the abort happens in the relay loop rather than in the fold:

- `crates/aisix-proxy/src/chat.rs` (`StreamOutputPolicy::BufferFull`, the `else` arm) sets `guard.comp().guardrail_blocked = true` directly;
-…

[Read the thread](https://github.com/api7/aisix/issues/1029) · 2026-08-22 · open · outside contributor · 0 comments

### realtime: post-auth error usage events carry no caller attribution (api_key_id, jwt identity)

The realtime handler authenticates inside `prepare()` (WebSocket subprotocol auth, not the `AuthenticatedKey` extractor), so `ClientContext` never carries the resolved identity. When a request fails AFTER authentication succeeds (model forbidden, rate limited, …), the error-path usage event is emitted with an empty `api_key_id` — and, since #931, also without the new `jwt_subject` / `jwt_provider` / `jwt_claim_mapping` attribution fields. The success path attributes correctly from the resolved…

[Read the thread](https://github.com/api7/aisix/issues/932) · 2026-08-11 · closed · outside contributor · 0 comments

### passthrough emits no UsageEvent at all (success or failure) — invisible to Logs, budget ledger and exporters

Found in the cross-endpoint parity audit following AISIX-Cloud#947 (see ai-gateway#695).

passthrough.rs records only `AccessLog` + `record_request` (~143-190). Passthrough traffic — success or failure — never appears in the UsageEvent stream, OTLP fan-out, budget ledger or per-PK telemetry. Token accounting absence is by design (raw tunnel, nothing parsed), but the complete absence of usage/failure events breaks the #655 convention every typed handler follows…

[Read the thread](https://github.com/api7/aisix/issues/699) · 2026-07-02 · closed · outside contributor · 0 comments

### MCP: usage events never reach OTLP exporters; no access log / request metrics; no upstream timeout

Found in the cross-endpoint parity audit following AISIX-Cloud#947 (see ai-gateway#695).

Three parity gaps in mcp.rs relative to every other handler:

1. `emit_tool_call_usage` writes only to the CP usage sink (`state.usage_sink.try_emit(\"mcp\", event)` at mcp.rs:310) — **no `otlp_fan_out.fan_out`**, so MCP usage never reaches any OTLP/SLS/Datadog exporter (every other emitter fans out, e.g. usage_attr.rs:137).
2. **No `AccessLog` and no `metrics.record_request`** anywhere in mcp.rs — /mcp…

[Read the thread](https://github.com/api7/aisix/issues/698) · 2026-07-02 · closed · outside contributor · 0 comments

### P1-9: MCP gateway (registration, transports, auth, access control, cost tracking)

## Problem

LiteLLM ships a full MCP (Model Context Protocol) gateway: register MCP servers, multiple transports (HTTP-streamable / SSE / stdio), auth methods (OAuth2 client-creds / **AWS SigV4 for Bedrock AgentCore** / API key / Bearer / Basic / static-headers), per-request \`x-mcp-{server}-{header}\` injection, access control by Key/Team/Org, server aliases, access groups, end-user attribution, semantic tool filtering, **MCP cost tracking**, MCP-specific guardrails, and auto-tool-execution…

[Read the thread](https://github.com/api7/aisix/issues/58) · 2026-04-26 · open · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/api7/aisix/issues).
