jordansissel/fpm · error · StandardError

Invalid tar stream, eof before end-of-tar record

Error message

Invalid tar stream, eof before end-of-tar record

What it means

FPM::Package::Apk#input parses an Alpine .apk tar stream record by record and terminates only after two consecutive zero-filled records (the standard end-of-tar marker). Hitting EOF before that marker means the stream ended early: the file is truncated or not a valid apk tar archive, and the conversion aborts.

Source

Thrown at lib/fpm/package/apk.rb:195

    empty_records = 0

    open(temporary_target_path, "wb") do |target_file|

      # Scan to find the location of the two contiguous null records
      open(target_path, "rb") do |file|

        until(empty_records == 2)

          header = file.read(TAR_CHUNK_SIZE)

          # clear off ownership info
          header = replace_ownership_headers(header, true)

          typeflag = header[TAR_TYPEFLAG_OFFSET]
          ascii_length = header[TAR_LENGTH_OFFSET_START..TAR_LENGTH_OFFSET_END]

          if(file.eof?())
            raise StandardError.new("Invalid tar stream, eof before end-of-tar record")
          end

          if(typeflag == "\0")
            empty_records += 1
            next
          end

          record_length = ascii_length.to_i(8)
          record_length = determine_record_length(record_length)

          target_file.write(header)
          target_file.write(file.read(record_length))
        end
      end
    end

    FileUtils::mv(temporary_target_path, target_path)
  end

View on GitHub (pinned to b6d77ba72a)

Solutions

  1. Validate the archive independently: tar tzf foo.apk >/dev/null — if tar errors too, the file is bad
  2. Re-download from a reliable mirror and verify size/sha256 against the APKINDEX checksum
  3. Confirm it is really an Alpine package: 'file foo.apk' should report gzip data, and the payload should list control.tar + data.tar members
  4. If it is a locally built apk, rebuild with abuild to regenerate a complete archive

Example fix

# before
fpm -s apk -t deb foo.apk   # truncated download => Invalid tar stream

# after
curl -fLO https://dl-cdn.alpinelinux.org/path/foo.apk
tar tzf foo.apk >/dev/null && fpm -s apk -t deb foo.apk
Defensive patterns

Strategy: validation

Validate before calling

unless system('tar', 'tzf', 'pkg.apk', out: File::NULL, err: File::NULL)
  abort 'apk archive is truncated/corrupt; re-download before converting'
end

Try / catch

begin
  pkg = FPM::Package::Apk.new
  pkg.input('pkg.apk')
rescue StandardError => e
  warn "invalid apk stream (#{e.message}); verify with: tar tzf pkg.apk"
  raise
end

Prevention

When it happens

Trigger: Running 'fpm -s apk -t deb foo.apk' where foo.apk is a partially downloaded package, an HTML error page saved with a .apk extension, or has a corrupted gzip layer so reads run dry before the terminator.

Common situations: Interrupted downloads or flaky mirrors; curl/wget without -f saving a 404 page as the package; passing a repository index file instead of the actual package; disk-full truncation of cached artifacts.

Related errors


AI-assisted analysis of jordansissel/fpm@b6d77ba72a (2026-08-21). Data as JSON: /api/errors/747629ef48180c62. Report an issue: GitHub.