/errors/tar/cowardly-refusing-to-create-an-empty-archive
tar: Cowardly refusing to create an empty archive
- tool
- tar
- exit code
- 2
- versions
- GNU tar 1.x
- os
- linux
tar: Cowardly refusing to create an empty archive is GNU tar's message when you use -c (create) and list no files. Add the files or directories after the archive name: tar -czf backup.tar.gz project/. The exit status is 2.
Reproduce it
tar -czf backup.tar.gzOutput · exit 2
tar: Cowardly refusing to create an empty archive Try 'tar --help' or 'tar --usage' for more information.
Fixes
mkdir project && echo hello > project/a.txt
tar -czf backup.tar.gz project/
tar -tzf backup.tar.gzOutput
project/ project/a.txt
A glob that matches nothing is another source of this error. In Bash an unmatched *.log stays as the literal text *.log, so tar then reports Cannot stat: No such file or directory instead. Check the pattern first:
ls *.log && tar -czf logs.tar.gz *.logEmpty variables and nullglob
In scripts, the file list often comes from a variable or a glob. If the variable is empty, or the glob matches nothing while nullglob is set, tar gets no names at all and stops with this error:
FILES=""
tar -czf b.tgz $FILES
echo "exit status: $?"
shopt -s nullglob
tar -czf c.tgz *.logOutput · exit 2
tar: Cowardly refusing to create an empty archive Try 'tar --help' or 'tar --usage' for more information. exit status: 2 tar: Cowardly refusing to create an empty archive Try 'tar --help' or 'tar --usage' for more information.
Guard the call, or pass the list with -T (--files-from). With an empty list file GNU tar does not refuse: it writes an empty archive and exits with 0, which is often what a nightly job wants.
files=(*.log)
if [ -e "${files[0]}" ]; then tar -czf logs.tgz "${files[@]}"; else echo "no logs to archive"; fi
find . -name '*.log' | tar -czf logs.tgz -T -
echo "exit status: $?, members: $(tar -tzf logs.tgz | wc -l)"Output
no logs to archive exit status: 0, members: 0
How to recognise the cause
| What you see | Likely cause |
|---|---|
| Cowardly refusing ... after a typed command | Nothing after the archive name, or -f bundled before other letters |
| Cowardly refusing ... from a script or cron job | An empty variable or a nullglob glob expanded to no names |
| Cannot stat: No such file or directory | A glob matched nothing and bash passed it literally (no nullglob) |
| tar: no files or directories specified | The same problem reported by bsdtar (macOS, Windows tar.exe) |
The order of options matters because -f takes the next word as the archive name. tar -czf backup.tar.gz project/ is correct; tar -cfz backup.tar.gz project/ creates an archive named z.
To create archives of absolute paths without warnings, see Removing leading / from member names; to unpack them, tar -xzf.
FAQ
How do I create an empty tar archive on purpose?
Give GNU tar an empty file list instead of no names at all, for example tar -cf empty.tar --files-from=/dev/null. tar then writes a valid archive with no members and exits with status 0.
What does bsdtar print instead?
bsdtar, the tar on macOS and the tar.exe in Windows, reports tar: no files or directories specified and exits with status 1. The cause and the fix are the same.
Why does my script fail only on some days?
The list of files is computed at run time. When a variable or a glob with nullglob expands to nothing, for example on a day with no new logs, tar receives no names and refuses.