{"record":{"id":"30e290c84036ff8b","repo":"JuliusBrussee/caveman","slug":"azure-api-version-q-is-not-on-the-allowlist","errorCode":null,"errorMessage":"azure api-version %q is not on the allowlist","messagePattern":"azure api-version %q is not on the allowlist","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/providers/azureopenai/azure_routing.go","lineNumber":64,"sourceCode":"\t\t}\n\t\treturn nil\n\t}\n\tif !legacyChatCompletionsRoute(u.Path) {\n\t\treturn fmt.Errorf(\"azure legacy inference path %q is not supported\", u.Path)\n\t}\n\tversions := u.Query()[\"api-version\"]\n\tif len(versions) > 1 {\n\t\treturn fmt.Errorf(\"azure request has duplicate api-version values\")\n\t}\n\tversion := \"\"\n\tif len(versions) == 1 {\n\t\tversion = versions[0]\n\t}\n\tif version == \"\" {\n\t\treturn fmt.Errorf(\"azure request missing api-version\")\n\t}\n\tif !apiVersionAllowed(version) {\n\t\treturn fmt.Errorf(\"azure api-version %q is not on the allowlist\", version)\n\t}\n\treturn nil\n}\n\nfunc foundryV1InferenceRoute(path string) bool {\n\tpath = strings.TrimPrefix(path, \"/azure\")\n\tswitch path {\n\tcase \"/openai/v1/chat/completions\", \"/openai/v1/responses\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc legacyChatCompletionsRoute(path string) bool {\n\tpath = strings.TrimPrefix(path, \"/azure\")\n\tparts := strings.Split(strings.Trim(path, \"/\"), \"/\")\n\tif len(parts) != 5 || parts[0] != \"openai\" || parts[1] != \"deployments\" ||","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/providers/azureopenai/azure_routing.go#L46-L82","documentation":"Legacy-route api-version values are checked against an allowlist: built-in dates 2024-02-01, 2024-06-01, 2024-08-01-preview, 2024-10-21, 2025-01-01-preview, 2025-03-01-preview, 2025-04-01-preview, 'preview', 'latest' — overridable via the comma-separated CAVE_AZURE_API_VERSION_ALLOWLIST env var. Pinning versions prevents clients from selecting unverified or deprecated Azure API behavior through the proxy.","triggerScenarios":"Sending ?api-version=2023-05-15 (older than the floor) or a brand-new date the build predates; setting CAVE_AZURE_API_VERSION_ALLOWLIST to a narrower list that no longer contains the version your SDK sends.","commonSituations":"An older SDK pinned to a pre-2024 version; a newly released Azure version not yet added to the built-in list; an operator tightened the env allowlist and forgot a client still on the old value.","solutions":["Switch the client to a version in the built-in list (e.g. 2024-10-21 or 2025-04-01-preview).","If the version is verified in your environment, extend the allowlist: CAVE_AZURE_API_VERSION_ALLOWLIST=2024-10-21,2023-05-15.","Check the env var for typos — note it REPLACES the default list entirely, so include every version you need."],"exampleFix":"# before\nexport CAVE_AZURE_API_VERSION_ALLOWLIST=2024-10-21\ncurl \"...?api-version=2025-04-01-preview\"   # rejected\n\n# after\nexport CAVE_AZURE_API_VERSION_ALLOWLIST=2024-10-21,2025-04-01-preview\ncurl \"...?api-version=2025-04-01-preview\"","handlingStrategy":"validation","validationCode":"allowed := map[string]bool{}\nfor _, v := range strings.Split(os.Getenv(\"CAVE_AZURE_API_VERSION_ALLOWLIST\"), \",\") {\n    if v = strings.TrimSpace(v); v != \"\" {\n        allowed[v] = true\n    }\n}\nversion := u.Query().Get(\"api-version\")\nif !allowed[version] {\n    return fmt.Errorf(\"api-version %q not allowlisted; add it to CAVE_AZURE_API_VERSION_ALLOWLIST or use a listed version\", version)\n}","typeGuard":"func apiVersionAllowed(version string) bool {\n    for _, v := range allowlist() { // env override or built-in defaults\n        if v == version {\n            return true\n        }\n    }\n    return false\n}","tryCatchPattern":"if err := validateAzureRequest(req.URL); err != nil {\n    if strings.Contains(err.Error(), \"not on the allowlist\") {\n        http.Error(w, \"api-version rejected; pin a listed version or extend CAVE_AZURE_API_VERSION_ALLOWLIST\", http.StatusBadRequest)\n        return\n    }\n    http.Error(w, err.Error(), http.StatusBadRequest)\n}","preventionTips":["Pin clients to a current allowlisted version (e.g. 2024-10-21).","Remember CAVE_AZURE_API_VERSION_ALLOWLIST replaces the default list — include every version in use.","Re-check the allowlist when upgrading client SDKs."],"tags":["go","azure","allowlist","versioning","configuration"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}