henrygd/beszel · error

container info request failed: %s: %s

Error message

container info request failed: %s: %s

What it means

getContainerInfo fetches full container inspect JSON from the Docker API. This error is thrown on a non-200 response and includes both the HTTP status and up to 1024 bytes of the response body, so the daemon's own error message (e.g. 'No such container') is visible. Decode failures after 200 are returned separately as raw errors.

Source

Thrown at agent/docker.go:833

func (dm *dockerManager) getContainerInfo(ctx context.Context, containerID string) ([]byte, error) {
	endpoint, err := buildDockerContainerEndpoint(containerID, "json", nil)
	if err != nil {
		return nil, err
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
	if err != nil {
		return nil, err
	}

	resp, err := dm.client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(io.LimitReader(resp.Body, 1024))
		return nil, fmt.Errorf("container info request failed: %s: %s", resp.Status, strings.TrimSpace(string(body)))
	}

	// Remove sensitive environment variables from Config.Env
	var containerInfo map[string]any
	if err := json.NewDecoder(resp.Body).Decode(&containerInfo); err != nil {
		return nil, err
	}
	if config, ok := containerInfo["Config"].(map[string]any); ok {
		delete(config, "Env")
	}

	return json.Marshal(containerInfo)
}

// getLogs fetches the logs for a container
func (dm *dockerManager) getLogs(ctx context.Context, containerID string) (string, error) {
	query := url.Values{
		"stdout": []string{"1"},

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Read the embedded body in the message — it usually says exactly why (e.g. no such container)
  2. Re-list containers and use a fresh ID; the container may have been removed
  3. Retry on 5xx; fail fast on 404
  4. Check daemon logs if 500s persist

Example fix

// before: assume info always exists
info, err := getContainerInfo(id)
process(info)
// after
info, err := getContainerInfo(id)
if err != nil {
    if strings.Contains(err.Error(), "404") { return nil } // container gone
    return err
}
process(info)
Defensive patterns

Strategy: try-catch

Validate before calling

// refresh the ID before inspecting
ids := listContainerIDs() // from a current /containers/json call
// only inspect ids present in this set

Try / catch

info, err := getContainerInfo(id)
if err != nil {
    if strings.Contains(err.Error(), "404") {
        return nil // container removed; not fatal
    }
    return err
}

Prevention

When it happens

Trigger: The container inspect HTTP call returns non-200 — 404 for unknown/removed container, 400 for malformed ID that slipped past validation, 5xx from an overloaded or restarting daemon.

Common situations: Requesting details for a container that exited and was auto-removed (--rm); race between listing and inspecting containers; Docker daemon under memory pressure returning 500.

Related errors


AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31). Data as JSON: /api/errors/812777c31550eaa7. Report an issue: GitHub.