hashicorp/nomad · error

failed to read intro token file: %w

Error message

failed to read intro token file: %w

What it means

Once the intro token path is confirmed a regular file, readIntroTokenFile reads it with helper.ReadFileContent. Any read failure (permission denied at read time, I/O error, file vanished between stat and read) is wrapped as 'failed to read intro token file'. On success the trimmed contents become cfg.IntroToken.

Source

Thrown at command/agent/agent.go:884

		}
		return err
	}

	fileStat, err := rootFile.Stat()
	if err != nil {
		return fmt.Errorf("failed to stat intro token file: %w", err)
	}

	// If the file exists and is a file, attempt to read the contents and set
	// the intro token. Any error is logged for the operator to investigate but
	// does not block the agent from starting.
	if fileStat.IsDir() {
		return fmt.Errorf("intro token file is a directory")
	}

	content, err := helper.ReadFileContent(rootFile)
	if err != nil {
		return fmt.Errorf("failed to read intro token file: %w", err)
	}

	cfg.IntroToken = strings.TrimSpace(string(content))
	return nil
}

// convertClientConfig takes an agent config and log output and returns a client
// Config. There may be missing fields that must be set by the agent. To do this
// call finalizeServerConfig
func convertClientConfig(agentConfig *Config) (*clientconfig.Config, error) {
	// Set up the configuration
	conf := agentConfig.ClientConfig
	if conf == nil {
		conf = clientconfig.DefaultConfig()
	}
	conf.Servers = agentConfig.Client.Servers
	conf.DevMode = agentConfig.DevMode
	conf.EnableDebug = agentConfig.EnableDebug

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. chmod/chown so the Nomad agent user can read the file (chmod 600, chown nomad).
  2. Re-create the token file if it was rotated/deleted during startup, then restart or reload the agent.
  3. Check filesystem health/mount options if reads fail despite correct permissions.

Example fix

// before (shell)
-rw------- 1 root root intro-token  # nomad user cannot read
// after (shell)
chown nomad:nomad intro-token && chmod 600 intro-token
Defensive patterns

Strategy: validation

Validate before calling

f, err := os.Open(path)
if err != nil {
  return fmt.Errorf("cannot read intro token file %q: %w", path, err)
}
f.Close()

Try / catch

if err := readIntroTokenFile(cfg, path); err != nil {
  if errors.Is(err, os.ErrPermission) {
    log.Errorf("fix ownership/mode of %s for the nomad user", path)
  }
  return err
}

Prevention

When it happens

Trigger: The file exists and is not a directory but cannot be read by the agent process: wrong ownership/mode, storage I/O failure, or a race where the file is removed between Stat and ReadFileContent, from finalizeClientConfig.

Common situations: File mode 0600 owned by root while Nomad runs unprivileged; rotated/deleted secret files during agent reload; failing disks or read-only mounts with permission quirks.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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