{"record":{"id":"a2d4956020fd772d","repo":"hashicorp/nomad","slug":"failed-to-read-intro-token-file-w","errorCode":null,"errorMessage":"failed to read intro token file: %w","messagePattern":"failed to read intro token file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/agent.go","lineNumber":884,"sourceCode":"\t\t}\n\t\treturn err\n\t}\n\n\tfileStat, err := rootFile.Stat()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to stat intro token file: %w\", err)\n\t}\n\n\t// If the file exists and is a file, attempt to read the contents and set\n\t// the intro token. Any error is logged for the operator to investigate but\n\t// does not block the agent from starting.\n\tif fileStat.IsDir() {\n\t\treturn fmt.Errorf(\"intro token file is a directory\")\n\t}\n\n\tcontent, err := helper.ReadFileContent(rootFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read intro token file: %w\", err)\n\t}\n\n\tcfg.IntroToken = strings.TrimSpace(string(content))\n\treturn nil\n}\n\n// convertClientConfig takes an agent config and log output and returns a client\n// Config. There may be missing fields that must be set by the agent. To do this\n// call finalizeServerConfig\nfunc convertClientConfig(agentConfig *Config) (*clientconfig.Config, error) {\n\t// Set up the configuration\n\tconf := agentConfig.ClientConfig\n\tif conf == nil {\n\t\tconf = clientconfig.DefaultConfig()\n\t}\n\tconf.Servers = agentConfig.Client.Servers\n\tconf.DevMode = agentConfig.DevMode\n\tconf.EnableDebug = agentConfig.EnableDebug","sourceCodeStart":866,"sourceCodeEnd":902,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/agent.go#L866-L902","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["chmod/chown so the Nomad agent user can read the file (chmod 600, chown nomad).","Re-create the token file if it was rotated/deleted during startup, then restart or reload the agent.","Check filesystem health/mount options if reads fail despite correct permissions."],"exampleFix":"// before (shell)\n-rw------- 1 root root intro-token  # nomad user cannot read\n// after (shell)\nchown nomad:nomad intro-token && chmod 600 intro-token","handlingStrategy":"validation","validationCode":"f, err := os.Open(path)\nif err != nil {\n  return fmt.Errorf(\"cannot read intro token file %q: %w\", path, err)\n}\nf.Close()","typeGuard":null,"tryCatchPattern":"if err := readIntroTokenFile(cfg, path); err != nil {\n  if errors.Is(err, os.ErrPermission) {\n    log.Errorf(\"fix ownership/mode of %s for the nomad user\", path)\n  }\n  return err\n}","preventionTips":["chmod 600 + chown to the Nomad service user for token files.","Re-run secret provisioning after token rotation and before reloads.","Avoid deleting/replacing token files while the agent is starting."],"tags":["filesystem","nomad","permissions"],"backgroundTag":"permission-denied","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}