如何修复ERR_INVALID_CHUNKED_ENCODING错误?Clojure代理Grafana异常
Let's break down what's happening here: that ERR_INVALID_CHUNKED_ENCODING error almost always means your proxy is messing up how it handles HTTP chunked responses from Grafana. When Grafana sends a chunked response (which it often does for dynamic content like dashboards), your Clojure app needs to forward that response exactly as-is—no modifying headers, no buffering the entire response, no accidentally adding conflicting headers like Content-Length.
Here's how to fix this step by step:
1. Use a Purpose-Built Proxy Middleware
Stop rolling your own proxy logic with clj-http or raw HTTP clients—they’re not designed to handle streaming proxying correctly for chunked responses. Instead, use ring-proxy, a Ring middleware built specifically for this use case.
First, add the dependency to your project.clj:
[ring/ring-proxy "0.2.5"] ;; Use the latest version available
Then, set up your routes to proxy /grafana paths to Grafana's port:
(ns proxy-app.core (:require [compojure.core :refer [defroutes GET]] [ring.proxy :refer [proxy-request]] [ring.adapter.jetty :as jetty] [ring.middleware.conditional :refer [wrap-conditional]] [ring.middleware.gzip :refer [wrap-gzip]])) ;; Route all /grafana* requests to Grafana (defroutes app-routes (GET "/grafana*" request ;; Strip the "/grafana" prefix from the URI before proxying (proxy-request (update request :uri #(subs % 7)) "http://127.0.0.1:3000"))) ;; Wrap with middleware, but exclude /grafana from gzip (Grafana may already compress responses) (def app (-> app-routes (wrap-conditional #(not (.startsWith (:uri %) "/grafana")) wrap-gzip))) (defn -main [] (jetty/run-jetty app {:port 80}))
2. Why This Works
proxy-requeststreams the response directly from Grafana to the browser without buffering it in memory. This preserves the original chunked encoding structure.- It automatically forwards all response headers from Grafana (including
Transfer-Encoding: chunked) and ensures conflicting headers likeContent-Lengtharen’t added accidentally. - The
wrap-conditionalline disables gzip compression for/grafanarequests—if your app was compressing responses that Grafana already compressed, this would corrupt the chunked encoding.
3. Common Mistakes to Avoid
- Don’t manually copy headers/body: If you were using
clj-httpto fetch the response and then returning it as a Ring response, you’re likely stripping the chunked encoding metadata.ring-proxyhandles this correctly out of the box. - Don’t mix Transfer-Encoding and Content-Length: Grafana sends
Transfer-Encoding: chunked(noContent-Length), so your proxy must not add aContent-Lengthheader—this confuses the browser into expecting a fixed-length response instead of chunks. - Check for interfering middleware: Any middleware that modifies response bodies or headers (like compression, content-type override) can break chunked encoding. Exclude
/grafanapaths from these middlewares.
4. Verify the Fix
After deploying this code:
- Open Chrome DevTools > Network tab.
- Visit
http://127.0.0.1/grafana. - Check the response headers for the main request: you should see
Transfer-Encoding: chunkedand noContent-Lengthheader. - The response body should load without the encoding error, and Grafana’s UI should render correctly.
If you still see issues, double-check that your URI stripping is correct (e.g., /grafana/dashboards becomes /dashboards when proxied) and that no other middleware is modifying the response.
内容的提问来源于stack exchange,提问作者Edmond

