{"record":{"id":"ae2880d761f9fd32","repo":"hashicorp/packer","slug":"error-preparing-shell-script-s","errorCode":null,"errorMessage":"Error preparing shell script: %s","messagePattern":"Error preparing shell script: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/shell/provisioner.go","lineNumber":204,"sourceCode":"\n\treturn nil\n}\n\nfunc (p *Provisioner) Provision(ctx context.Context, ui packersdk.Ui, comm packersdk.Communicator, generatedData map[string]interface{}) error {\n\tif generatedData == nil {\n\t\tgeneratedData = make(map[string]interface{})\n\t}\n\tp.generatedData = generatedData\n\n\tscripts := make([]string, len(p.config.Scripts))\n\tcopy(scripts, p.config.Scripts)\n\n\t// If we have an inline script, then turn that into a temporary\n\t// shell script and use that.\n\tif p.config.Inline != nil {\n\t\ttf, err := tmp.File(\"packer-shell\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Error preparing shell script: %s\", err)\n\t\t}\n\t\tdefer os.Remove(tf.Name())\n\n\t\t// Set the path to the temporary file\n\t\tscripts = append(scripts, tf.Name())\n\n\t\t// Write all inline commands to this buffer\n\t\tcommandBuffer := strings.Builder{}\n\t\tfor _, command := range p.config.Inline {\n\t\t\tp.config.ctx.Data = generatedData\n\t\t\tcommand, err := interpolate.Render(command, &p.config.ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"Error interpolating Inline: %s\", err)\n\t\t\t}\n\t\t\tif _, err := fmt.Fprintf(&commandBuffer, \"%s\\n\", command); err != nil {\n\t\t\t\treturn fmt.Errorf(\"Error preparing shell script: %s\", err)\n\t\t\t}\n\t\t}","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/shell/provisioner.go#L186-L222","documentation":"When the shell provisioner is configured with inline scripts, Provision creates a temporary file (tmp.File(\"packer-shell\")) to hold the joined inline commands. If creating that temp file fails, the error wraps the OS-level cause and provisioning aborts before any script runs.","triggerScenarios":"tmp.File fails because the host temp directory (TMPDIR/TMP/TEMP or /tmp) is missing, full, has wrong permissions, or the process lacks write access; also possible under restrictive sandboxing or noexec/filled inodes.","commonSituations":"CI containers with read-only /tmp or tiny tmpfs; Packer run as a restricted user; TMPDIR pointing to a nonexistent directory; disk quota exhausted on the host.","solutions":["Check the wrapped cause and verify the host temp directory exists and is writable (echo $TMPDIR; touch $TMPDIR/test).","Free disk space / inodes on the partition holding the temp directory.","Set TMPDIR (or TMP/TEMP on Windows) to a writable location when the default is restricted.","Alternatively use a scripts file instead of inline to avoid temp-file creation."],"exampleFix":"// before (shell)\nTMPDIR=/nonexistent packer build template.pkr.hcl\n// after\nTMPDIR=/var/tmp packer build template.pkr.hcl","handlingStrategy":"validation","validationCode":"# shell: confirm temp dir is writable before building\ntest -d \"$TMPDIR\" && test -w \"$TMPDIR\" && touch \"$TMPDIR/.writecheck\" && rm \"$TMPDIR/.writecheck\" || echo \"TMPDIR not writable\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify TMPDIR/TEMP points to an existing writable directory in CI images.","Watch disk space and inode usage on the temp partition.","Prefer scripts files over inline in sandboxes with restricted /tmp.","Run builds as a user with temp-directory write access."],"tags":["filesystem","temp-file","shell","host-environment"],"backgroundTag":"temp-file-creation-failed","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}