hashicorp/nomad · error

failed to generate envoy bootstrap config: %w

Error message

failed to generate envoy bootstrap config: %w

What it means

The envoy_bootstrap_hook generates the Envoy bootstrap configuration for a Connect sidecar/gateway during Prestart. It first loads the Consul SI (service identity) token with maybeLoadSIToken; if that fails, it logs an error and returns 'failed to generate envoy bootstrap config' wrapping the cause. Without the SI token the bootstrap file cannot be generated correctly.

Source

Thrown at client/allocrunner/taskrunner/envoy_bootstrap_hook.go:307

	// Set runtime environment variables for the envoy admin and ready listeners.
	resp.Env = map[string]string{
		helper.CleanEnvVar(envoyAdminBindEnvPrefix+serviceName, '_'): envoyAdminBind,
		helper.CleanEnvVar(envoyReadyBindEnvPrefix+serviceName, '_'): envoyReadyBind,
	}

	// Envoy bootstrap configuration may contain a Consul token, so write
	// it to the secrets directory like Vault tokens.
	bootstrapFilePath := filepath.Join(req.TaskDir.SecretsDir, "envoy_bootstrap.json")

	// Write everything related to the command to enable debugging
	bootstrapStderrPath := filepath.Join(req.TaskDir.LogDir, "envoy_bootstrap.stderr.0")
	bootstrapEnvPath := filepath.Join(req.TaskDir.SecretsDir, ".envoy_bootstrap.env")
	bootstrapCmdPath := filepath.Join(req.TaskDir.SecretsDir, ".envoy_bootstrap.cmd")

	siToken, err := h.maybeLoadSIToken(req.Task.Name, req.TaskDir.SecretsDir)
	if err != nil {
		h.logger.Error("failed to generate envoy bootstrap config", "sidecar_for", service.Name)
		return fmt.Errorf("failed to generate envoy bootstrap config: %w", err)
	}
	h.logger.Debug("check for SI token for task", "task", req.Task.Name, "exists", siToken != "")

	proxyID := h.proxyServiceID(h.alloc.TaskGroup, service)
	bootstrap := h.newEnvoyBootstrapArgs(service, grpcAddr, envoyAdminBind, envoyReadyBind, siToken, bootstrapFilePath, proxyID)

	// Create command line arguments
	bootstrapArgs := bootstrap.args()

	// Write args to file for debugging
	argsFile, err := os.Create(bootstrapCmdPath)
	if err != nil {
		return fmt.Errorf("failed to write bootstrap command line: %w", err)
	}
	defer argsFile.Close()
	if _, err := io.WriteString(argsFile, strings.Join(bootstrapArgs, " ")+"\n"); err != nil {
		return fmt.Errorf("failed to encode bootstrap command line: %w", err)
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check the wrapped error to see if the token file is missing vs unreadable
  2. Ensure the task has a Consul service identity (consul.token / workload identity) configured
  3. Verify Consul is >= 1.8 and ACLs are enabled/compatible with SI token flow
  4. Confirm the task's SecretsDir exists and is populated before Prestart completes
  5. Retry the allocation; the hook regenerates the bootstrap on restart

Example fix

// before: no identity configured for the connect service
service { name = "api" connect { sidecar_service {} } } // missing token
// after: ensure Consul SI token is provisioned to the task
// enable Consul SI token injection (Consul >=1.8, acls enabled) or supply
// identity { kind = "consul"; name = "api" } in the task group
Defensive patterns

Strategy: validation

Validate before calling

// before Prestart, verify the SI token artifact is present
if _, err := os.Stat(filepath.Join(secretsDir, consulTokenFilename)); err != nil {
    return fmt.Errorf("consul SI token missing for envoy bootstrap: %w", err)
}

Try / catch

if err := hook.Prestart(req); err != nil {
    if strings.Contains(err.Error(), "failed to generate envoy bootstrap config") {
        log.Printf("envoy bootstrap failed: %v; check Consul SI token provisioning", err)
    }
    return err
}

Prevention

When it happens

Trigger: maybeLoadSIToken returns an error: the consul token file is missing from the task's SecretsDir when Connect requires it, unreadable permissions, or an error reading/writing the token path inside the secrets directory.

Common situations: Task running Consul Connect services without the Consul SI identity/Token configured; Consul version too old to support SI tokens; secrets dir not mounted or cleaned before the hook runs; Consul ACL setup incomplete.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/015548821acab383. Report an issue: GitHub.