Skip to content

/errors/tar/cowardly-refusing-to-create-an-empty-archive

tar: Cowardly refusing to create an empty archive

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · tar (GNU tar) 1.35updated
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

bash
tar -czf backup.tar.gz

Output · exit 2

tar: Cowardly refusing to create an empty archive
Try 'tar --help' or 'tar --usage' for more information.

Fixes

bash
mkdir project && echo hello > project/a.txt
tar -czf backup.tar.gz project/
tar -tzf backup.tar.gz

Output

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:

bash
ls *.log && tar -czf logs.tar.gz *.log

Empty 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:

bash
FILES=""
tar -czf b.tgz $FILES
echo "exit status: $?"
shopt -s nullglob
tar -czf c.tgz *.log

Output · 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.

bash
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 seeLikely cause
Cowardly refusing ... after a typed commandNothing after the archive name, or -f bundled before other letters
Cowardly refusing ... from a script or cron jobAn empty variable or a nullglob glob expanded to no names
Cannot stat: No such file or directoryA glob matched nothing and bash passed it literally (no nullglob)
tar: no files or directories specifiedThe 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.

Sources