glanceapp/glance · error
decoding response: %w
Error message
decoding response: %w
What it means
The response body from /containers/json could not be JSON-decoded into the container list. Docker's API always returns valid JSON, so this means the body was truncated, an HTML error page was returned by an intermediary, or the endpoint is not the Docker API at all.
Source
Thrown at internal/glance/widget-docker-containers.go:337
request, err := http.NewRequestWithContext(ctx, "GET", "http://"+hostname+"/containers/json?all="+fetchAll, nil)
if err != nil {
return nil, fmt.Errorf("creating request: %w", err)
}
response, err := client.Do(request)
if err != nil {
return nil, fmt.Errorf("sending request to socket: %w", err)
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("non-200 response status: %s", response.Status)
}
var containers []dockerContainerJsonResponse
if err := json.NewDecoder(response.Body).Decode(&containers); err != nil {
return nil, fmt.Errorf("decoding response: %w", err)
}
for i := range containers {
container := &containers[i]
name := strings.TrimLeft(itemAtIndexOrDefault(container.Names, 0, ""), "/")
if name == "" {
continue
}
overrides, ok := labelOverrides[name]
if !ok {
continue
}
if container.Labels == nil {
container.Labels = make(dockerContainerLabels)
}View on GitHub (pinned to 91324e8de7)
Solutions
- Fetch the raw body manually with curl and inspect whether it is JSON: curl --unix-socket ... | head -c 200
- Point the source directly at the Docker API endpoint without proxies
- If truncation is suspected, fix the unstable network link to the remote Docker host
Defensive patterns
Strategy: try-catch
Validate before calling
body, err := io.ReadAll(io.LimitReader(response.Body, 1<<20))
if err == nil && len(body) > 0 && body[0] != '{' && body[0] != '[' {
return fmt.Errorf("non-JSON response from %s (first byte %q)", hostname, body[0])
} Try / catch
var containers []dockerContainerJsonResponse
if err := json.NewDecoder(response.Body).Decode(&containers); err != nil {
slog.Warn("docker response not JSON — is a proxy in front of the API?", "host", hostname, "error", err)
return nil, err
} Prevention
- Never put a caching/HTML proxy between the widget and the Docker API
- Alert on content-type: application/json absence in responses from the configured source
When it happens
Trigger: A proxy returns an HTML error page with a 200 status; connection dropped mid-body (unexpected EOF); non-Docker service on the target port returning 200 with non-JSON content.
Common situations: tcp:// source pointing at a web server; flaky network truncating responses; intermediate caching proxy mangling the response.
Related errors
- non-200 response status: %s
- body must be a string when body-type is 'string'
- no `{REQUEST-URL}` placeholder specified
- could not solve reddit challenge
- failed to retrieve any content
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/d331b12d713bed50.
Report an issue: GitHub.