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

  1. Fetch the raw body manually with curl and inspect whether it is JSON: curl --unix-socket ... | head -c 200
  2. Point the source directly at the Docker API endpoint without proxies
  3. 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

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


AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15). Data as JSON: /api/errors/d331b12d713bed50. Report an issue: GitHub.