{"record":{"id":"4eb3c10efcd5eaee","repo":"kopia/kopia","slug":"unable-to-write-webdav-key","errorCode":null,"errorMessage":"unable to write WebDAV key","messagePattern":"unable to write WebDAV key","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"repo/blob/rclone/rclone_storage.go","lineNumber":290,"sourceCode":"\t// password file for rclone webdav server.\n\ttemporaryHtpassword := filepath.Join(td, \"htpasswd\")\n\n\tdefer func() {\n\t\t// if we return this function without setting Storage, make sure to clean everything up.\n\t\tif r.Storage == nil {\n\t\t\tr.Close(ctx) //nolint:errcheck\n\t\t}\n\t}()\n\n\t// write TLS files.\n\t//nolint:mnd\n\tcert, key, err := tlsutil.GenerateServerCertificate(ctx, 2048, 365*24*time.Hour, []string{\"127.0.0.1\"})\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"unable to generate server certificate\")\n\t}\n\n\tif err = tlsutil.WritePrivateKeyToFile(temporaryKeyPath, key); err != nil {\n\t\treturn nil, errors.Wrap(err, \"unable to write WebDAV key\")\n\t}\n\n\tif err = tlsutil.WriteCertificateToFile(temporaryCertPath, cert); err != nil {\n\t\treturn nil, errors.Wrap(err, \"unable to write WebDAV cert\")\n\t}\n\n\t// temporary username and password to be used when communicating with rclone\n\twebdavUsername := \"u\" + uuid.New().String()\n\twebdavPassword := \"p\" + uuid.New().String()\n\n\tif err = htpasswd.SetPassword(temporaryHtpassword, webdavUsername, webdavPassword, htpasswd.HashAPR1); err != nil {\n\t\treturn nil, errors.Wrap(err, \"unable to write htpasswd file\")\n\t}\n\n\trcloneExe := defaultRCloneExe\n\tif opt.RCloneExe != \"\" {\n\t\trcloneExe = opt.RCloneExe\n\t}","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/repo/blob/rclone/rclone_storage.go#L272-L308","documentation":"After generating the TLS keypair, New() writes the private key to a temp file via tlsutil.WritePrivateKeyToFile so rclone can serve HTTPS WebDAV. Failure writing that key file is wrapped as 'unable to write WebDAV key'.","triggerScenarios":"tlsutil.WritePrivateKeyToFile(temporaryKeyPath, key) fails — temp dir deleted mid-run, permissions problem, or disk full.","commonSituations":"Temp cleaner daemon removing the kopia-rclone dir concurrently; full disk on /tmp; security software blocking key material written to disk.","solutions":["Confirm the temporary directory (td from os.MkdirTemp) still exists and is writable","Check free space on the filesystem holding the temp dir","Exclude kopia temp paths from aggressive tmp-cleaners","Re-run the connect; a fresh temp dir is created each time"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"td, err := os.MkdirTemp(\"\", \"kopia-rclone-probe\")\nif err != nil { return err }\ndefer os.RemoveAll(td)\nprobe := filepath.Join(td, \"probe\")\nif err := os.WriteFile(probe, []byte(\"x\"), 0o600); err != nil {\n    return fmt.Errorf(\"temp dir not writable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"_, err := rclone.New(ctx, opt, isCreate)\nif err != nil && strings.Contains(err.Error(), \"unable to write WebDAV key\") {\n    log.Printf(\"failed writing TLS key to temp dir: %v; check TMPDIR permissions/space\", err)\n}","preventionTips":["Exclude kopia temp dirs from tmp-cleaner jobs","Keep free space headroom on the temp filesystem","Check SELinux/AppArmor policies for temp write access"],"tags":["tls","filesystem","file-write","kopia"],"backgroundTag":"file-write-failed","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}