{"record":{"id":"8d9c46c6b0db7925","repo":"vitessio/vitess","slug":"failed-to-render-config-to-tempfile-v","errorCode":null,"errorMessage":"failed to render config to tempfile: %v","messagePattern":"failed to render config to tempfile: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"go/viperutil/debug/handler.go","lineNumber":65,"sourceCode":"\t\tacl.SendError(w, err)\n\t\treturn\n\t}\n\n\tv := registry.Combined()\n\tformat := strings.ToLower(r.URL.Query().Get(\"format\"))\n\tswitch {\n\tcase format == \"\":\n\t\tv.DebugTo(w)\n\tcase slice.Any(viper.SupportedExts, func(ext string) bool { return ext == format }):\n\t\t// Got a supported format; write the config to a tempfile in that format,\n\t\t// then copy it to the response.\n\t\t//\n\t\t// (Sadly, viper does not yet have a WriteConfigTo(w io.Writer), so we have\n\t\t// to do this little hacky workaround).\n\t\tv.SetConfigType(format)\n\t\ttmp, err := os.CreateTemp(\"\", \"viper_debug\")\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to render config to tempfile: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\tdefer os.Remove(tmp.Name())\n\n\t\tif err := v.WriteConfigAs(tmp.Name()); err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to render config to tempfile: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\tif _, err := io.Copy(w, tmp); err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to write rendered config: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\tdefault:\n\t\thttp.Error(w, \"unsupported config format\", http.StatusBadRequest)\n\t}\n}\n","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/viperutil/debug/handler.go#L47-L83","documentation":"The viperutil debug HTTP handler renders the current config to a temp file because viper lacks WriteConfigTo(w io.Writer). If os.CreateTemp fails, it returns 500 with 'failed to render config to tempfile'. This means the environment cannot supply a temp file at all.","triggerScenarios":"Hitting the debug config endpoint (HandlerFunc) when os.CreateTemp(\"\", \"viper_debug\") fails — typically /tmp not existing, being full, or permission denied for the process.","commonSituations":"Containers with read-only root filesystem and no writable TMPDIR; disk-full on /tmp; TMPDIR pointing to a nonexistent directory; hardened sandboxes blocking temp file creation.","solutions":["Ensure TMPDIR points to a writable directory (or mount a writable tmpfs at /tmp) and restart the process.","Free disk space on the partition backing the temp directory.","Check permissions on the temp directory for the process user.","As a workaround, view the config via other debug endpoints or logs if temp files cannot be enabled."],"exampleFix":"// before (docker run)\ndocker run --read-only vitess/lite ...\n// after\ndocker run --read-only --tmpfs /tmp:rw,size=64m vitess/lite ...","handlingStrategy":"validation","validationCode":"tmp := os.TempDir()\nif fi, err := os.Stat(tmp); err != nil || !fi.IsDir() {\n\treturn fmt.Errorf(\"temp dir %s unusable: %v\", tmp, err)\n}\ntest, err := os.CreateTemp(tmp, \"probe\")\nif err != nil {\n\treturn err\n}\ntest.Close()\nos.Remove(test.Name())","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set TMPDIR to a writable volume in containers, especially with read-only root filesystems.","Monitor disk space on the temp partition.","Add a startup health check that creates and removes a temp file."],"tags":["http","filesystem","tempfile","config"],"backgroundTag":"temp-file-creation-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}