gzip: stdin: invalid compressed data--format violated
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now
원인은 거의 둘 중 하나다. 파일이 애초에 gzip 아카이브가 아니거나, 전송 도중 잘렸거나 손상된 것이다.
확장자는 아무것도 보장하지 않는다. 실제 내용을 본다.
file archive.tar.gz
gzip compressed data 가 아니라면 압축 파일이 아니다. 컨테이너 레지스트리의 blob 디렉터리(.../docker/v2/blobs/sha256_...)처럼 해시 이름이 붙은 파일은 레이어 tar 일 수도 있고 JSON 매니페스트일 수도 있어서, 하나를 골라 tar xzf 하면 당연히 실패한다. 레지스트리 데이터는 파일을 직접 푸는 것이 아니라 docker pull · skopeo copy · oras 같은 도구로 다뤄야 한다.
zstd · xz · bzip2 로 압축된 파일에 -z 를 주어도 같은 오류가 난다. 요즘 tar 는 압축 방식을 자동으로 판별하므로 형식을 모를 때는 옵션을 빼고 실행하는 편이 낫다.
tar xf archive.tar.gz
gzip 계층과 tar 계층을 나눠서 본다. gzip 검사가 통과했는데 tar 나열이 실패하면 압축은 멀쩡하고 아카이브 구조가 깨진 것이다.
gzip -t archive.tar.gz && echo "gzip OK"
tar tzf archive.tar.gz > /dev/null && echo "tar OK"
디렉터리 안의 파일을 한꺼번에 검사한다.
for f in *.tar.gz; do
if ! gzip -t "$f" 2>/dev/null; then
echo "gzip 손상: $f"
elif ! tar tzf "$f" >/dev/null 2>&1; then
echo "tar 손상: $f"
fi
done
원본과 크기·해시를 대조하는 것이 가장 확실하다.
ls -l archive.tar.gz
sha256sum archive.tar.gz
원본 쪽에서 만든 체크섬 파일이 있으면 그대로 검증한다.
sha256sum -c archive.tar.gz.sha256
scp · sftp 로 옮기다 끊긴 파일은 다시 받는 것이 정답이다. 이어받기가 필요하면 rsync --partial --progress 또는 rsync -avP 를 쓴다. 대용량이라면 나눠 보내고 합치는 방식이 재전송 비용을 줄인다.
완전 복구는 불가능하지만 깨진 지점 앞까지는 꺼낼 수 있다.
gzip -dc archive.tar.gz > archive.tar 2>/dev/null
tar xvf archive.tar --ignore-zeros 2>&1 | tail
--ignore-zeros 는 중간의 널 블록을 건너뛴다. 이렇게 꺼낸 파일은 마지막 몇 개가 잘려 있을 수 있으므로 반드시 내용을 확인한다.