hashicorp/nomad · error

failed to write bootstrap command line: %w

Error message

failed to write bootstrap command line: %w

What it means

For debugging, the envoy bootstrap hook writes the generated envoy bootstrap command-line arguments to .envoy_bootstrap.cmd in the task's SecretsDir. This error wraps an os.Create failure for that debug file; it is about persisting the debug artifact, not about generating the bootstrap itself.

Source

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

	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)
	}

	// Create environment
	bootstrapEnv := bootstrap.env(h.groupEnv())

	// Write env to file for debugging
	envFile, err := os.Create(bootstrapEnvPath)
	if err != nil {
		return fmt.Errorf("failed to write bootstrap environment: %w", err)
	}
	defer envFile.Close()
	envEnc := json.NewEncoder(envFile)
	envEnc.SetIndent("", "    ")
	if err := envEnc.Encode(bootstrapEnv); err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check the wrapped OS error (disk full? no such directory? permission denied?)
  2. Verify the task SecretsDir exists and is writable by the Nomad client user
  3. Free disk space on the client data volume if ENOSPC
  4. Fix SELinux/AppArmor denials if they block creation in SecretsDir
  5. Retry the allocation after filesystem repair
Defensive patterns

Strategy: validation

Validate before calling

if info, err := os.Stat(secretsDir); err != nil || !info.IsDir() {
    return fmt.Errorf("secrets dir %s not ready: %w", secretsDir, err)
}
if err := unix.Access(secretsDir, unix.W_OK); err != nil {
    return fmt.Errorf("secrets dir %s not writable: %v", secretsDir, err)
}

Try / catch

if err := hook.Prestart(req); err != nil {
    var pe *os.PathError
    if errors.As(err, &pe) && strings.Contains(err.Error(), "bootstrap command line") {
        log.Printf("debug artifact write failed on %s: %v", pe.Path, pe.Err)
    }
}

Prevention

When it happens

Trigger: os.Create(bootstrapCmdPath) fails because SecretsDir does not exist, is read-only, is out of disk, or permissions forbid the Nomad user from creating files there.

Common situations: Full disk on the client; secrets directory removed by a prior failed task step; restrictive umask or SELinux policy blocking file creation in the secrets dir.

Understand the failure class

Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.

Related errors


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