vitessio/vitess · error · errUnsupportedDeCompressionEngine

%w value: %q

Error message

%w value: %q

What it means

When a backup was compressed with an external compression engine, restore tries newExternalDecompressor; but if the configured decompression engine is 'external' while the context does not provide one, this error is returned wrapping errUnsupportedDeCompressionEngine. It means Vitess was asked to decompress with an external tool that is not actually usable in this restore.

Source

Thrown at go/vt/mysqlctl/builtinbackupengine.go:1587

	deCompressionEngine := bm.CompressionEngine
	if deCompressionEngine == "" {
		deCompressionEngine = PgzipCompressor
	}

	externalDecompressorCmd := resolveExternalDecompressor(bm.ExternalDecompressor)

	var decompressor io.ReadCloser
	var err error
	if externalDecompressorCmd != "" {
		if deCompressionEngine == ExternalCompressor {
			deCompressionEngine = externalDecompressorCmd
			decompressor, err = newExternalDecompressor(ctx, deCompressionEngine, reader, params.Logger)
		} else {
			decompressor, err = newBuiltinDecompressor(deCompressionEngine, reader, params.Logger)
		}
	} else {
		if deCompressionEngine == ExternalCompressor {
			return nil, nil, fmt.Errorf("%w value: %q", errUnsupportedDeCompressionEngine, ExternalCompressor)
		}
		decompressor, err = newBuiltinDecompressor(deCompressionEngine, reader, params.Logger)
	}
	if err != nil {
		return nil, nil, vterrors.Wrap(err, "can't create decompressor")
	}

	closer := ioutil.NewTimeoutCloser(ctx, decompressor, closeTimeout)
	decompressStats := params.Stats.Scope(stats.Operation("Decompressor:Read"))
	wrappedReader := ioutil.NewMeteredReader(decompressor, decompressStats.TimedIncrementBytes)

	cleanup := func() error {
		params.Logger.Infof("closing decompressor for %s", name)
		closeAt := time.Now()
		cerr := closeWithRetry(ctx, params.Logger, closer, "decompressor")
		if cerr != nil {
			cerr = vterrors.Wrapf(cerr, "failed to close decompressor %v", name)
			params.Logger.Error(cerr)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Ensure the same external compression tool configured at backup time is installed on the restore host and on PATH.
  2. Verify the external compressor/decompressor command configuration (externalcompression settings) is present on the tablet.
  3. Or re-take the backup using a builtin engine (gzip, zstd, etc.) if you do not want the external dependency.
  4. Confirm the backup manifest's CompressionEngine matches what the host can handle.

Example fix

// before
// backup taken with: --compression-engine external, restore host has no external decompressor
// after
// install the tool on the tablet host, or take backups with a builtin engine:
// vtctldclient Backup --compression-engine zstd
Defensive patterns

Strategy: validation

Validate before calling

// before restoring, confirm the host can handle the manifest's engine:
if manifest.CompressionEngine == "external" {
	// check the external decompressor is configured/installed on this host
	if !externalDecompressionConfigured() {
		return fmt.Errorf("backup uses external compression; tool not available")
	}
}

Try / catch

decompressor, fileList, err := openDecompressor(...)
if err != nil && errors.Is(err, errUnsupportedDeCompressionEngine) {
	// install/configure the external tool or re-take backup with builtin engine
}

Prevention

When it happens

Trigger: RestoreFromBackup decompresses a backup file whose BackupManifest compressionEngine is ExternalCompressor, but no external decompressor command is configured/available in the restore params, so the code falls into the builtin branch and rejects ExternalCompressor there.

Common situations: Backup taken with --compression-engine=external but restore host lacks the external decompressor binary or the external_decompression command config; config lost between backup and restore hosts.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/ffa3cc79a4acfd54. Report an issue: GitHub.