juanfont/headscale · warning

extracting logs: %w

Error message

extracting logs: %w

What it means

Wrapped error from extractContainerLogs while saving a container's stdout/stderr logs after an integration-test run. The `hi` test runner extracts artifacts (per AGENTS.md, ~100 MB of logs per run under control_logs/{runID}/) from every hs-*/ts-* container, and this is the outer wrapper around that extraction. The underlying cause is almost always a Docker API call failure (container already removed, daemon unreachable, cancelled context), not the wrapper itself.

Source

Thrown at cmd/hi/docker.go:769

			}
		}
	}

	return testRunContainers
}

// extractContainerArtifacts saves logs and tar files from a container.
func extractContainerArtifacts(ctx context.Context, cli *client.Client, containerID, containerName, logsDir string, verbose bool) error {
	// Ensure the logs directory exists
	err := os.MkdirAll(logsDir, defaultDirPerm)
	if err != nil {
		return fmt.Errorf("creating logs directory: %w", err)
	}

	// Extract container logs
	err = extractContainerLogs(ctx, cli, containerID, containerName, logsDir, verbose)
	if err != nil {
		return fmt.Errorf("extracting logs: %w", err)
	}

	return nil
}

// extractContainerLogs saves the stdout and stderr logs from a container to files.
func extractContainerLogs(ctx context.Context, cli *client.Client, containerID, containerName, logsDir string, verbose bool) error {
	// Get container logs
	logReader, err := cli.ContainerLogs(ctx, containerID, container.LogsOptions{
		ShowStdout: true,
		ShowStderr: true,
		Timestamps: false,
		Follow:     false,
		Tail:       "all",
	})
	if err != nil {
		return fmt.Errorf("getting container logs: %w", err)
	}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Run `docker ps -a --filter name=hs-` to check whether the container still exists; re-run with `go run ./cmd/hi cleanup` first to clear stale state
  2. Verify the Docker daemon is healthy with `docker info` and restart it if the connection dropped
  3. Increase the run timeout (runConfig.Timeout) so extraction is not racing a cancelled context
  4. Read the wrapped error text — it names the exact failing stage (getting logs, demultiplexing, or writing files) which is the real problem
Defensive patterns

Strategy: fallback

Validate before calling

// Before extraction, confirm the container still exists
if _, err := cli.ContainerInspect(ctx, containerID); err != nil {
    // skip artifact extraction instead of failing the whole cleanup
    log.Printf("container %s gone, skipping log extraction", containerName)
    return nil
}

Prevention

When it happens

Trigger: Calling extractContainerArtifacts after a test run when the container was force-removed before log extraction (e.g. cleanup ran first), when the Docker daemon connection dropped, or when ctx was cancelled/timed out before cli.ContainerLogs could complete.

Common situations: Stale containers from a previous run that `hi cleanup` already reaped; Docker Desktop restarting mid-run; the run timeout firing and cancelling the context during artifact extraction; disk pressure in the Docker VM.

Related errors


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/56dff8409186651b. Report an issue: GitHub.