Skip to content

Instantly share code, notes, and snippets.

@kavirajk
Created November 2, 2025 22:16
Show Gist options
  • Save kavirajk/102b90118dfca1e4eb52cc9ae9a79c04 to your computer and use it in GitHub Desktop.
Save kavirajk/102b90118dfca1e4eb52cc9ae9a79c04 to your computer and use it in GitHub Desktop.
Demo Zero Chunk bug with ClickHouse server
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
// This demonstrates how the client WOULD work if ClickHouse properly
// terminated chunked encoding with 0\r\n\r\n
func main() {
url := "http://localhost:8123/?database=default&wait_end_of_query=0&max_threads=1"
query := "SELECT throwIf(number=3, 'there is a exception') FROM system.numbers SETTINGS max_block_size=1 FORMAT Native"
client := &http.Client{
Timeout: 120 * time.Second,
}
req, err := http.NewRequest("POST", url, strings.NewReader(query))
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating request: %v\n", err)
os.Exit(1)
}
resp, err := client.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "Error making request: %v\n", err)
os.Exit(1)
}
defer resp.Body.Close()
// With proper chunked encoding, this would work!
body, err := io.ReadAll(resp.Body)
if err != nil {
// Currently fails here with: unexpected EOF
// Would work if ClickHouse sent 0\r\n\r\n terminator
fmt.Fprintf(os.Stderr, "❌ Error reading body: %v\n", err)
fmt.Fprintf(os.Stderr, " This happens because ClickHouse doesn't send proper chunk terminator!\n")
fmt.Fprintf(os.Stderr, " Captured %d bytes before error\n", len(body))
os.Exit(1)
}
// If we got here, chunked encoding was proper
fmt.Printf("✅ Successfully read complete response (%d bytes)\n", len(body))
// Save to file
os.WriteFile("response.native", body, 0644)
// Check for exception in the body
if bytes.Contains(body, []byte("__exception__")) {
fmt.Println("\n⚠️ Query completed with exception (streamed in body)")
// Extract exception details
exceptionStart := bytes.Index(body, []byte("__exception__"))
if exceptionStart >= 0 {
exceptionData := body[exceptionStart:]
// Find the error code
if codeIdx := bytes.Index(exceptionData, []byte("Code: ")); codeIdx >= 0 {
errorLine := exceptionData[codeIdx:]
endLine := bytes.Index(errorLine, []byte("\n"))
if endLine > 0 {
fmt.Printf("Exception: %s\n", errorLine[:endLine])
}
}
}
os.Exit(1)
}
// Success - no exception
fmt.Println("\n✅ Query completed successfully")
fmt.Println("Data contains valid results")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment