{"record":{"id":"e92205a3dd210404","repo":"juanfont/headscale","slug":"creating-temp-dir-w","errorCode":null,"errorMessage":"creating temp dir: %w","messagePattern":"creating temp dir: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/dev/main.go","lineNumber":104,"sourceCode":"\t}\n\n\thttp.DefaultClient.Timeout = 2 * time.Second\n\thttp.DefaultClient.CheckRedirect = func(*http.Request, []*http.Request) error {\n\t\treturn http.ErrUseLastResponse\n\t}\n\n\terr := run()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\nfunc run() error {\n\tmetricsPort := *port + 1010 // default 9090\n\n\ttmpDir, err := os.MkdirTemp(\"\", \"headscale-dev-\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating temp dir: %w\", err)\n\t}\n\n\tif !*keep {\n\t\tdefer os.RemoveAll(tmpDir)\n\t}\n\n\t// Write config.\n\tconfigPath := filepath.Join(tmpDir, \"config.yaml\")\n\tconfigContent := fmt.Sprintf(\n\t\tdevConfig,\n\t\t*port, *port, metricsPort,\n\t\ttmpDir, tmpDir, tmpDir,\n\t)\n\n\terr = os.WriteFile(configPath, []byte(configContent), 0o600)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"writing config: %w\", err)\n\t}","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/cmd/dev/main.go#L86-L122","documentation":"\"creating temp dir: %w\" at cmd/dev/main.go:104 wraps the error from os.MkdirTemp(\"\", \"headscale-dev-\") in headscale's developer bootstrapping tool. The dev command builds a scratch directory for its generated config.yaml and binary before running a local server. Failure means the OS could not create a directory in the default temp location (TMPDIR, typically /tmp).","triggerScenarios":"Running `go run ./cmd/dev` when TMPDIR is unset to a non-existent/unwritable path, /tmp is full (ENOSPC), or the disk quota for temp files is exhausted; the wrapped error identifies syscall.EACCES, ENOSPC, ENOENT, etc.","commonSituations":"See trigger scenarios.","solutions":["Check the wrapped error: ENOSPC means free space in /tmp; EACCES means fix permissions or set TMPDIR to a writable dir","Export TMPDIR=/path/to/writable/dir and re-run `go run ./cmd/dev`","Clean stale headscale-dev-* directories if /tmp is full"],"exampleFix":"# before\nTMPDIR=/nonexistent go run ./cmd/dev\n\n# after\nmkdir -p \"$HOME/tmp\" && TMPDIR=\"$HOME/tmp\" go run ./cmd/dev","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(os.TempDir()); err != nil {\n\treturn fmt.Errorf(\"TMPDIR %s unusable: %w\", os.TempDir(), err)\n}","typeGuard":null,"tryCatchPattern":"tmpDir, err := os.MkdirTemp(\"\", \"headscale-dev-\")\nif err != nil {\n\t// read wrapped cause: EACCES -> set TMPDIR; ENOSPC -> free space\n\tif errors.Is(err, syscall.ENOSPC) {\n\t\treturn fmt.Errorf(\"temp filesystem full: %w\", err)\n\t}\n\treturn fmt.Errorf(\"creating temp dir: %w\", err)\n}","preventionTips":["Keep space free on the filesystem backing TMPDIR","Set TMPDIR to a known-writable local path in constrained environments"],"tags":["dev-tooling","filesystem","temp-dir","environment"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}