{"record":{"id":"403bb0d2bc3ea824","repo":"netbirdio/netbird","slug":"remove-empty-output-file-w","errorCode":null,"errorMessage":"remove empty output file: %w","messagePattern":"remove empty output file: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/cmd/capture.go","lineNumber":178,"sourceCode":"\toutPath, _ := cmd.Flags().GetString(\"output\")\n\tif outPath == \"\" {\n\t\treturn os.Stdout, func() error { return nil }, nil\n\t}\n\n\tf, err := os.CreateTemp(filepath.Dir(outPath), filepath.Base(outPath)+\".*.tmp\")\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"create output file: %w\", err)\n\t}\n\ttmpPath := f.Name()\n\treturn f, func() error {\n\t\tvar merr *multierror.Error\n\t\tif err := f.Close(); err != nil {\n\t\t\tmerr = multierror.Append(merr, fmt.Errorf(\"close output file: %w\", err))\n\t\t}\n\t\tfi, statErr := os.Stat(tmpPath)\n\t\tif statErr != nil || fi.Size() == 0 {\n\t\t\tif rmErr := os.Remove(tmpPath); rmErr != nil && !os.IsNotExist(rmErr) {\n\t\t\t\tmerr = multierror.Append(merr, fmt.Errorf(\"remove empty output file: %w\", rmErr))\n\t\t\t}\n\t\t\treturn nberrors.FormatErrorOrNil(merr)\n\t\t}\n\t\tif err := os.Rename(tmpPath, outPath); err != nil {\n\t\t\tmerr = multierror.Append(merr, fmt.Errorf(\"rename output file: %w\", err))\n\t\t\treturn nberrors.FormatErrorOrNil(merr)\n\t\t}\n\t\tcmd.PrintErrf(\"Wrote %s\\n\", outPath)\n\t\treturn nberrors.FormatErrorOrNil(merr)\n\t}, nil\n}\n\nfunc handleCaptureError(err error) error {\n\tif s, ok := status.FromError(err); ok {\n\t\treturn fmt.Errorf(\"%s\", s.Message())\n\t}\n\treturn err\n}","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/capture.go#L160-L196","documentation":"In output finalization, when the temp file is empty (zero packets captured) or its Stat failed, the cleanup removes the temp file so no stray .tmp file is left behind. This error means os.Remove failed with something other than 'file does not exist' — e.g. permission loss on the directory between creation and removal, or the file being held immutable. It is accumulated into the returned multierror.","triggerScenarios":"Directory permissions changed or the process lost write permission on the output directory between CreateTemp and cleanup; another process/user deleted or locked the temp file on platforms that disallow removal; immutable attribute (chattr +i) set on the file.","commonSituations":"Security tooling quarantining pcap-like temp files mid-run; permission-revoking MAC policy (SELinux) reacting to the new file; extremely rare in normal single-user CLI use — usually seen together with unusual cleanup failures of the same run.","solutions":["Check directory permissions and MAC denials (ausearch -m AVC for SELinux) for the output directory","Ensure no antivirus/EDR is removing or locking the .tmp files; exclude the capture directory if policy allows","Retry with an output directory you fully control (e.g. under /tmp)","If Stat failed rather than Remove, the temp file may already be gone — verify no stray *.tmp remains and treat the message as diagnostic"],"exampleFix":"# before: writing where a policy tool intervenes\nnetbird debug capture -o /opt/protected/x.pcap\n\n# after: use a controlled writable directory\nnetbird capture -o /tmp/x.pcap 2>/dev/null || netbird debug capture -o \"$HOME/x.pcap\"","handlingStrategy":"fallback","validationCode":"// Reduce exposure: use a dedicated, policy-free output dir owned by the invoker:\n// mkdir -p ~/netbird-captures && netbird debug capture -o ~/netbird-captures/x.pcap","typeGuard":null,"tryCatchPattern":"// Best-effort cleanup: ignore remove failures for empty temp files, they are cosmetic:\nif rmErr := os.Remove(tmpPath); rmErr != nil && !os.IsNotExist(rmErr) {\n    log.Warnf(\"leftover temp file %s: %v\", tmpPath, rmErr)\n}","preventionTips":["Keep the output directory owned by the invoking user to avoid permission drift mid-run","Exclude capture directories from antivirus/EDR quarantine policies","If a stray .tmp remains, delete it manually; it contains no useful data when empty"],"tags":["capture","filesystem","cleanup","permissions","cli"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}