Docs

API7 Gateway 3.9.11

This version extends secret references ($secret://, $env://) to work with all plugins centrally.

Release Date: 2026-04-30

Upgrade Notes

Upgrade note — Secret references CP→DP compatibility

This version extends secret references ($secret://, $env://) to work with all plugins centrally. After upgrading the Control Plane to 3.9.11, if you configure secret references in plugin fields that previously did not support them, a Data Plane still running 3.9.10 or earlier will not resolve those references — it will pass the literal $secret://... string to the plugin.

Recommended upgrade path: Upgrade all Data Planes to 3.9.11 before configuring secret references in newly-supported plugin fields. Plugins that already supported secrets in previous versions (jwt-auth, openid-connect, limit-count, authz-keycloak, csrf, limit-req, limit-conn) are not affected.

Features

Plugins

  • AI Proxy (opens in Plugin Hub docs)
    • Added a passthrough protocol adapter that proxies unrecognized API formats (such as /v1/images/generations) through to the upstream without transformation. Previously, requests that did not match a known protocol (OpenAI Chat, Completions, Embeddings, etc.) were rejected.
    • Rewrote the Anthropic-to-OpenAI protocol converter using a whitelist body construction approach. This prevents Anthropic-specific fields (such as metadata, top_k, thinking, and output_config) from leaking through to OpenAI-compatible upstream providers, and improves conversion accuracy for tool use, system prompts, and multimodal content.
    • Upstream nginx variables ($upstream_status, $upstream_addr, $upstream_response_time, $upstream_header_time, $upstream_connect_time, $upstream_response_length) are now populated in access logs when ai-proxy uses cosocket transport to call LLM backends. Previously, these variables were empty because nginx's upstream module was bypassed.
  • OAS Validator (opens in Plugin Hub docs)
    • Replaced the Go FFI-based OpenAPI validator with a pure-Lua implementation (lua-resty-openapi-validator). Internal benchmarks on a real-world large-scale OpenAPI specification (Stripe, ~414 endpoints) show the new validator is 2–7x faster per-request and compiles the spec 20x faster, while also reducing gateway image size by eliminating the Go shared library. The new validator additionally fixes correctness issues with path parameter routing, nullable schemas, allOf/anyOf merging, and adds support for validating form-encoded request bodies that the previous implementation could not handle.
  • All plugins now support $secret:// and $env:// references in any configuration field automatically. Previously, only a handful of plugins (jwt-auth, openid-connect, limit-count, authz-keycloak, csrf, limit-req, limit-conn) had explicit secret reference support. This removes the need for each plugin to implement secret resolution individually.

Data Plane

  • A new distroless gateway image variant (api7-ee-3-gateway-distroless) is now available. Built from scratch with only the shared libraries, CA certificates, and timezone data needed to run the gateway, it eliminates OS packages that carry CVEs but are unused at runtime.

Console (Dashboard)

  • Configuration compatibility warnings and errors are now displayed in a separate clickable badge on Data Plane instance cards. Clicking the badge opens a modal with a detailed table of all configuration issues (resource type, ID, severity level, and message), making it easier to identify and resolve config schema problems without confusing them with version compatibility status.

Fixes

Plugins

  • AI Proxy Multi (opens in Plugin Hub docs)
    • Fixed issue: After the Control Plane pushed a config update, health check validation logged noisy warnings (unable to construct upstream for plugin: ai-proxy-multi) because DNS resolution state was lost during the config table replacement.
  • AI Rate Limiting (opens in Plugin Hub docs)
    • Fixed issue: AI instance names containing dots (such as Qwen3.5-397B-10.249.238.157) caused HTTP 500 errors because the name was incorrectly interpreted as a ctx.var path expression instead of a constant key.
  • AI Request Rewrite (opens in Plugin Hub docs)
    • Fixed issue: Requests with no body produced a vague upstream error instead of returning a clear HTTP 400 Bad Request.
  • AI Prompt Template (opens in Plugin Hub docs)
    • Fixed issue: JSON parse error messages were garbled Lua table references (such as table: 0x...) instead of readable error strings.
  • OpenTelemetry (opens in Plugin Hub docs)
    • Fixed issue: Non-string values in additional_attributes (such as numbers or booleans from nginx variables) were silently dropped by the OpenTelemetry SDK. They are now coerced to strings before being added to spans.
  • Limit Count (opens in Plugin Hub docs)
    • Fixed issue: Redis credentials (redis_password, redis_username, sentinel_password) were embedded in rate-limiting group keys, exposing sensitive information in Redis keyspace and APISIX logs.
  • Traffic Split (Stream) (opens in Plugin Hub docs)
    • Fixed issue: ctx.var.route_id always returned nil in stream (L4) context, causing match conditions based on route_id in traffic-split rules to never match.
    • Fixed issue: When traffic-split selected an upstream via upstream_id in stream context, the selection was ignored and the route's original upstream was always used.

Control Plane

  • Fixed issue: Warning-level entries in the configuration compatibility report incorrectly caused Data Plane instances to display "Upgrade Recommended" even when the Control Plane and Data Plane versions matched.

Data Plane

  • Fixed issue: The batch processor entered an infinite timer loop during nginx worker shutdown, preventing graceful shutdown and flooding logs with [alert] messages.
  • Fixed issue: The batch processor's processed_entries counter was reset when stale buffers were cleaned up, breaking delivery metrics for batch-processing plugins (such as http-logger, kafka-logger).
  • Fixed issue: Active health check request_body configuration was silently ignored because the underlying healthcheck library expects the field to be named http_req_body. The schema field has been renamed to match.
  • Fixed issue: Sensitive field values were exposed in error logs when encrypt/decrypt operations failed. Error messages no longer include the raw value.
  • Fixed issue: During upgrades with newly added encrypt_fields, expected decrypt failures of pre-existing plaintext data generated noisy warn-level log entries. These are now logged at info level with an explanatory message.