{"record":{"id":"90bc769cb1197926","repo":"hashicorp/nomad","slug":"unexpected-supportedproxies-response-format-from-c","errorCode":null,"errorMessage":"unexpected SupportedProxies response format from Consul","messagePattern":"unexpected SupportedProxies response format from Consul","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/consul/connect_proxies.go","lineNumber":71,"sourceCode":"\t// For these cases, we can simply fallback to the old version of Envoy\n\t// that Nomad defaulted to back then - but not in this logic. Instead,\n\t// return nil so we can choose what to do at the caller.\n\n\txds, xdsExists := self[\"xDS\"]\n\tif !xdsExists {\n\t\treturn nil, nil\n\t}\n\n\tproxies, proxiesExists := xds[\"SupportedProxies\"]\n\tif !proxiesExists {\n\t\treturn nil, nil\n\t}\n\n\t// convert interface{} to map[string]interface{}\n\n\tintermediate, ok := proxies.(map[string]any)\n\tif !ok {\n\t\treturn nil, errors.New(\"unexpected SupportedProxies response format from Consul\")\n\t}\n\n\t// convert map[string]interface{} to map[string][]string\n\n\tresult := make(map[string][]string, len(intermediate))\n\tfor k, v := range intermediate {\n\n\t\t// convert interface{} to []interface{}\n\n\t\tif si, ok := v.([]any); ok {\n\t\t\tss := make([]string, 0, len(si))\n\t\t\tfor _, z := range si {\n\n\t\t\t\t// convert interface{} to string\n\n\t\t\t\tif s, ok := z.(string); ok {\n\t\t\t\t\tss = append(ss, s)\n\t\t\t\t}","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/consul/connect_proxies.go#L53-L89","documentation":"Proxies() in command/agent/consul/connect_proxies.go queries Consul's SupportedProxies endpoint via the agent's Consul client. The Consul HTTP API is expected to return a JSON object (map[string]any) of supported proxy kinds; if the decoded response is not a map, Nomad cannot convert it to its result type and returns this error. It almost always indicates the Consul agent responded with an unexpected or non-object payload rather than the documented schema.","triggerScenarios":"Calling Nomad's Proxies API path when the Consul agent behind the query returns a JSON array, string, or null for the SupportedProxies endpoint — e.g. an old or non-standard Consul version, a proxy/middlebox rewriting the response, or a custom/modified Consul build.","commonSituations":"Running Nomad against an outdated Consul version that predates the SupportedProxies endpoint (Consul may return an error body or different shape), pointing Nomad at a service-discovery shim instead of real Consul, or a load balancer returning an HTML/JSON error page that decodes to a non-map value.","solutions":["Verify the Consul agent version supports the SupportedProxies connect endpoint (Consul >= 1.x with connect enabled); upgrade Consul if it is old.","Check that the Nomad agent's consul.address points at a genuine Consul server, not a proxy or mock, and inspect the raw response with `curl http://<consul>/v1/agent/connect/proxies/...`.","Confirm Consul connect is enabled (`connect.enabled = true` in the Consul agent config) so the endpoint returns the documented object rather than an error payload.","Inspect Nomad server logs for the underlying Consul HTTP status; if Consul returned 404/50x, fix routing/auth before retrying."],"exampleFix":"// before: querying against Consul 1.2 without connect support\n// after: run a compatible Consul agent\n// consul.hcl\nconnect { enabled = true }","handlingStrategy":"type-guard","validationCode":"// verify Consul connect endpoint first\nresp, _ := http.Get(consulAddr + \"/v1/agent/connect/proxies/...\")\nvar raw any\njson.NewDecoder(resp.Body).Decode(&raw)\nif _, ok := raw.(map[string]any); !ok {\n    // abort: Consul version/build does not return the documented object\n}","typeGuard":"func isProxyMap(v any) bool {\n    _, ok := v.(map[string]any)\n    return ok\n}","tryCatchPattern":"if err := proxiesCall(); err != nil {\n    if strings.Contains(err.Error(), \"unexpected SupportedProxies response format\") {\n        log.Printf(\"Consul version/connect mismatch, skipping proxy support query: %v\", err)\n        return fallbackProxyList\n    }\n    return err\n}","preventionTips":["Pin Nomad and Consul to documented compatible version pairs.","Smoke-test `curl $CONSUL/v1/agent/connect/ca/roots` after Consul upgrades.","Never route Consul traffic through rewriting middleboxes in test environments."],"tags":["consul","connect-proxies","response-format"],"backgroundTag":"unexpected-response-format","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}