{"record":{"id":"8341668f64aef46f","repo":"hashicorp/nomad","slug":"failed-to-encode-bootstrap-environment-w","errorCode":null,"errorMessage":"failed to encode bootstrap environment: %w","messagePattern":"failed to encode bootstrap environment: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/taskrunner/envoy_bootstrap_hook.go","lineNumber":339,"sourceCode":"\t}\n\tdefer argsFile.Close()\n\tif _, err := io.WriteString(argsFile, strings.Join(bootstrapArgs, \" \")+\"\\n\"); err != nil {\n\t\treturn fmt.Errorf(\"failed to encode bootstrap command line: %w\", err)\n\t}\n\n\t// Create environment\n\tbootstrapEnv := bootstrap.env(h.groupEnv())\n\n\t// Write env to file for debugging\n\tenvFile, err := os.Create(bootstrapEnvPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to write bootstrap environment: %w\", err)\n\t}\n\tdefer envFile.Close()\n\tenvEnc := json.NewEncoder(envFile)\n\tenvEnc.SetIndent(\"\", \"    \")\n\tif err := envEnc.Encode(bootstrapEnv); err != nil {\n\t\treturn fmt.Errorf(\"failed to encode bootstrap environment: %w\", err)\n\t}\n\n\t// keep track of latest error returned from exec-ing consul envoy bootstrap\n\tvar cmdErr error\n\n\tbackoffOpts := decay.BackoffOptions{\n\t\tMaxSleepTime:   h.envoyBootstrapWaitTime,\n\t\tInitialGapSize: h.envoyBootstrapInitialGap,\n\t\tMaxJitterSize:  h.envoyBootstrapMaxJitter,\n\t\tSleeper:        h.envoyBootstrapExpSleep,\n\t}\n\n\terr = h.servicePreflightCheck(ctx, backoffOpts, proxyID)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Since Consul services are registered asynchronously with this task","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/taskrunner/envoy_bootstrap_hook.go#L321-L357","documentation":"In Nomad's envoy_bootstrap_hook Prestart, after writing secrets/envoy_bootstrap.json (the env file for the consul envoy bootstrap command), a json.Encoder writes the bootstrapEnv map to the file. This error wraps any failure of that Encode call, meaning the environment data could not be serialized to the env file on disk.","triggerScenarios":"envEnc.Encode(bootstrapEnv) returns a non-nil error during Prestart after the env file was created. In practice Encode on an open writable file rarely fails, but it can if the underlying write fails (disk full, I/O error, file closed/permission revoked mid-write) or if bootstrapEnv contains an unsupported type (e.g. a channel, func, or cyclic value would make Encode fail before writing).","commonSituations":"Disk-full or I/O problems on the host where the allocation's secrets dir lives; a code change introducing a non-JSON-serializable value into bootstrapEnv; unusual filesystem errors (NFS/EFS hiccups, quota exceeded) in the alloc dir.","solutions":["Check host disk space and alloc-dir filesystem health; retry the allocation.","Inspect the env file's permissions and that the secrets directory is writable by the Nomad client.","Retry the task; the Prestart hook failure is surfaced in the task events with this message.","If it reproduces on every run, check the Nomad version for bugs and verify no custom hooks mutate bootstrapEnv."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure the env file is writable and bootstrapEnv is JSON-safe before Prestart\nf, err := os.OpenFile(envFilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o640)\nif err != nil { return err }\nif _, err := f.Stat(); err != nil { return err }\nif _, err := json.Marshal(bootstrapEnv); err != nil { return fmt.Errorf(\"bootstrapEnv not JSON-serializable: %w\", err) }\nf.Close()","typeGuard":null,"tryCatchPattern":"err := hook.Prestart(ctx, req)\nif err != nil {\n    var recoverable *structs.RecoverableError\n    if errors.As(err, &recoverable) && recoverable.IsRecoverable() {\n        // reschedule/restart the task\n    } else {\n        // fail the allocation permanently and inspect disk/filesystem\n    }\n}","preventionTips":["Monitor alloc-dir disk usage and inode availability.","Keep the secrets directory owned/writable by the Nomad client user.","Avoid injecting non-serializable values into hook environment maps.","Enable Nomad client debug logs when filesystem I/O errors cluster on one host."],"tags":["go","json","encoding","nomad","envoy"],"backgroundTag":"json-encode-failed","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"}