amir20/dozzle · error

failed to listen

Error message

failed to listen: %w

What it means

Returned by AgentCmd.Run when net.Listen("tcp", args.Agent.Addr) fails to bind the gRPC listener. The address comes from --agent-addr (default :7007, env DOZZLE_AGENT_ADDR). Typical causes are the port already being used or binding to an address that does not exist on the host.

Solutions

  1. Check what holds the port: `lsof -i :7007` or `ss -ltnp | grep 7007`, then stop it.
  2. Change the port: --agent-addr :7008 or DOZZLE_AGENT_ADDR=:7008 (update the main server's agent endpoint too).
  3. If binding to a specific IP, confirm it exists on the host (`ip addr`).
  4. Kill leftover agent processes: `pkill dozzle`.
  5. Use a port above 1024 if running as non-root.

Example fix

// before
DOZZLE_AGENT_ADDR=127.0.0.1:7007 ./dozzle agent  # bind fails, IP not local
// after
DOZZLE_AGENT_ADDR=:7007 ./dozzle agent
Defensive patterns

Strategy: validation

Validate before calling

if ss -ltn | grep -q ':7007 '; then echo 'port 7007 already in use'; exit 1; fi

Try / catch

if err := agentCmd.Run(args, embeddedCerts); err != nil {
  if strings.Contains(err.Error(), "failed to listen") {
    log.Fatal().Err(err).Msg("port busy or invalid bind address; adjust --agent-addr")
  }
}

Prevention

When it happens

Trigger: Another dozzle agent (or any process) already listens on 7007; binding to a specific IP not assigned to the host; privileged port below 1024 without privileges; invalid host:port syntax.

Common situations: Two agents accidentally started on one host; old agent process still running after crash (check /tmp/dozzle-agent.addr); container network conflicts; changing DOZZLE_AGENT_ADDR to a typo'd host.

Related errors


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/73fd4f3f05f278f3. Report an issue: GitHub.

Appendix: source

Thrown at internal/support/cli/agent_command.go:156

	}
}

func (a *AgentCmd) Run(args Args, embeddedCerts embed.FS) error {
	if args.Mode != "server" {
		return fmt.Errorf("agent command is only available in server mode")
	}
	client, err := docker.NewLocalClient(args.Hostname)
	if err != nil {
		return fmt.Errorf("failed to create docker client: %w", err)
	}
	certs, err := ReadCertificates(embeddedCerts, args.CertPath, args.KeyPath)
	if err != nil {
		return fmt.Errorf("failed to read certificates: %w", err)
	}

	listener, err := net.Listen("tcp", args.Agent.Addr)
	if err != nil {
		return fmt.Errorf("failed to listen: %w", err)
	}
	const agentAddrFile = "/tmp/dozzle-agent.addr"
	if err := os.WriteFile(agentAddrFile, []byte(args.Agent.Addr), 0644); err != nil {
		return fmt.Errorf("failed to write agent address file: %w", err)
	}
	go StartEvent(args, "", client, "agent")

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	// Create shared client service (single ContainerStore for both agent server and notifications)
	clientService := docker_support.NewDockerClientService(client, args.Filter)

	// Create notification manager using the shared client service
	const notificationConfigPath = "./data/notifications.yml"
	clients := []container_support.ClientService{clientService}
	notificationManager := notification.NewManager(
		notification.NewContainerLogListener(ctx, clients),

View on GitHub (pinned to d9463cbe21)