You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ClickHouse server can return HTTP 200 OK while reporting a query failure via the X-ClickHouse-Exception-Code response header (the error text being in the body). This happens when:
The server already started streaming response headers before encountering an error mid-stream (chunked transfer; __exception__ marker not always present).
A distributed DDL via ON CLUSTER surfaces a per-shard error encoded inside a result block (see Error in server, but 200 response clickhouse-go#1398 — Sorting key contains nullable columns returned as HTTP/1.1 200 OK with the error inside the Native body and no __exception__ marker).
In clickhouse-http-client (the legacy v1 HTTP client used by jdbc-v1), two of the three HTTP connection providers only consult the HTTP status code and ignoreX-ClickHouse-Exception-Code when status is 200, even though the constant is defined in ClickHouseHttpProto.HEADER_EXCEPTION_CODE:
clickhouse-http-client/src/main/java/com/clickhouse/client/http/HttpUrlConnectionImpl.java (JDK HttpURLConnection), around line 176:
privatevoidcheckResponse(HttpURLConnectionconn) throwsIOException {
log.debug("http response code [%d]", conn.getResponseCode());
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
StringerrorCode = conn.getHeaderField("X-ClickHouse-Exception-Code");
...
}
// status 200 → returns; X-ClickHouse-Exception-Code never inspected
}
clickhouse-http-client/src/main/java11/com/clickhouse/client/http/HttpClientConnectionImpl.java (Java 11 HttpClient), around line 140:
Net effect (v1 path only): a query (especially Exec / INSERT / ON CLUSTER DDL) the server marks as failed via the response header on a 200 response is observed as success when jdbc-v1 is backed by HttpUrlConnectionImpl or HttpClientConnectionImpl. Risks: silent data loss, silent schema-change failure.
Note: jdbc-v1's default HTTP connection provider is ApacheHttpConnectionImpl (which is correct), so users on defaults are unaffected. Users who select HTTP_URL_CONNECTION or HTTP_CLIENT as the HTTP connection provider hit the bug. This is also adjacent to but distinct from #650 (mid-result error rows / __exception__ marker; blocked-by-clickhouse) — the fix here is purely client-side: inspect the header.
ClickHouse server version
Code analysis only; not verified against a running server. Server version available in test environment: 26.4.2.10. Behavior is consistent with prior server versions per the source bug.
Reproduction
Conceptual reproduction with a stub HTTP server (Java 11+ pseudocode using com.sun.net.httpserver):
Expected: ClickHouseException with code 44 (server's exception code from the header).
Actual (with HTTP_URL_CONNECTION or HTTP_CLIENT provider): no exception thrown; the call returns success.
A user-visible variant of this is the closed clickhouse-go#1398 and the source bug clickhouse-rs#255: distributed DDL with ON CLUSTER that the server reports failed via header on a 200 response.
Suggested fix
In each of the two affected providers, gate the early-return on both status and header presence (matching what ApacheHttpConnectionImpl and client-v2 already do):
StringerrorCode = r.headers().firstValue(ClickHouseHttpProto.HEADER_EXCEPTION_CODE).orElse("");
if (r.statusCode() == HttpURLConnection.HTTP_OK && errorCode.isEmpty()) {
returnr;
}
// fall through to existing error path
A small unit test against a stub HTTP server (as above) for each provider would lock the behavior down.
Link
Source bug: ClickHouse/clickhouse-rs#255
Related (user-reported manifestation in clickhouse-go, closed via server-side workaround): ClickHouse/clickhouse-go#1398
Adjacent existing issue in this repo (different root cause — mid-result error rows): #650
Central tracking: ClickHouse/integrations-ai-playground#147
Description
ClickHouse server can return
HTTP 200 OKwhile reporting a query failure via theX-ClickHouse-Exception-Coderesponse header (the error text being in the body). This happens when:__exception__marker not always present).ON CLUSTERsurfaces a per-shard error encoded inside a result block (see Error in server, but 200 response clickhouse-go#1398 —Sorting key contains nullable columnsreturned asHTTP/1.1 200 OKwith the error inside the Native body and no__exception__marker).In
clickhouse-http-client(the legacy v1 HTTP client used byjdbc-v1), two of the three HTTP connection providers only consult the HTTP status code and ignoreX-ClickHouse-Exception-Codewhen status is 200, even though the constant is defined inClickHouseHttpProto.HEADER_EXCEPTION_CODE:clickhouse-http-client/src/main/java/com/clickhouse/client/http/HttpUrlConnectionImpl.java(JDKHttpURLConnection), around line 176:clickhouse-http-client/src/main/java11/com/clickhouse/client/http/HttpClientConnectionImpl.java(Java 11HttpClient), around line 140:For comparison, the third legacy provider,
ApacheHttpConnectionImpl.checkResponse(line ~217), is correct — it gates on both:And
client-v2(current HTTP client,HttpAPIClientHelper.doPostRequestline ~584) is also correct:Net effect (v1 path only): a query (especially
Exec/INSERT/ON CLUSTERDDL) the server marks as failed via the response header on a 200 response is observed as success whenjdbc-v1is backed byHttpUrlConnectionImplorHttpClientConnectionImpl. Risks: silent data loss, silent schema-change failure.Note:
jdbc-v1's default HTTP connection provider isApacheHttpConnectionImpl(which is correct), so users on defaults are unaffected. Users who selectHTTP_URL_CONNECTIONorHTTP_CLIENTas the HTTP connection provider hit the bug. This is also adjacent to but distinct from #650 (mid-result error rows /__exception__marker;blocked-by-clickhouse) — the fix here is purely client-side: inspect the header.ClickHouse server version
Code analysis only; not verified against a running server. Server version available in test environment:
26.4.2.10. Behavior is consistent with prior server versions per the source bug.Reproduction
Conceptual reproduction with a stub HTTP server (Java 11+ pseudocode using
com.sun.net.httpserver):ClickHouseExceptionwith code 44 (server's exception code from the header).HTTP_URL_CONNECTIONorHTTP_CLIENTprovider): no exception thrown; the call returns success.A user-visible variant of this is the closed
clickhouse-go#1398and the source bugclickhouse-rs#255: distributed DDL withON CLUSTERthat the server reports failed via header on a 200 response.Suggested fix
In each of the two affected providers, gate the early-return on both status and header presence (matching what
ApacheHttpConnectionImplandclient-v2already do):clickhouse-http-client/src/main/java/com/clickhouse/client/http/HttpUrlConnectionImpl.java(~line 178):clickhouse-http-client/src/main/java11/com/clickhouse/client/http/HttpClientConnectionImpl.java(~line 142):A small unit test against a stub HTTP server (as above) for each provider would lock the behavior down.
Link
Source bug: ClickHouse/clickhouse-rs#255
Related (user-reported manifestation in clickhouse-go, closed via server-side workaround): ClickHouse/clickhouse-go#1398
Adjacent existing issue in this repo (different root cause — mid-result error rows): #650
Central tracking: ClickHouse/integrations-ai-playground#147