crowdsecurity/crowdsec · critical

failed to decompress obfuscator wasm: %w

Error message

failed to decompress obfuscator wasm: %w

What it means

This error is returned by compileObfuscatorModule when io.ReadAll on the gzip reader of the embedded obfuscator WASM fails mid-stream. The gzip header was valid but the payload is truncated or corrupt. It is raised once (guarded by sync.Once) during NewChallengeRuntime.

Source

Thrown at pkg/appsec/challenge/challenge.go:324

// all appsec runners. Pass WithXxx options to override defaults.
// compileObfuscatorModule decompresses the baked-in obfuscator WASM (once,
// process-wide) and compiles it for the given runtime. Pre-compiling lets each
// ObfuscateJS call merely instantiate the module instead of re-parsing the WASM
// bytes, which would otherwise cost ~4-5s per call.
func compileObfuscatorModule(ctx context.Context, r wazero.Runtime) (wazero.CompiledModule, error) {
	var obfuscatorWasmErr error

	obfuscatorWasmOnce.Do(func() {
		zr, err := gzip.NewReader(bytes.NewReader(obfuscatorWasmGz))
		if err != nil {
			obfuscatorWasmErr = fmt.Errorf("failed to create gzip reader for obfuscator wasm: %w", err)
			return
		}
		defer zr.Close()

		obfuscatorWasm, err = io.ReadAll(zr)
		if err != nil {
			obfuscatorWasmErr = fmt.Errorf("failed to decompress obfuscator wasm: %w", err)
			return
		}
	})

	if obfuscatorWasmErr != nil {
		return nil, obfuscatorWasmErr
	}

	compiledMod, err := r.CompileModule(ctx, obfuscatorWasm)
	if err != nil {
		return nil, fmt.Errorf("failed to compile obfuscator wasm module: %w", err)
	}

	return compiledMod, nil
}

// compilerSupported mimics the check performed by wazero for SSE4.1
// We cannot rely in wazero on the wazero check, as it is used to choose whether to use the compiler or interpreter mode

View on GitHub (pinned to 909b515798)

Solutions

  1. Rebuild and redeploy the crowdsec binary from a clean source tree (make build).
  2. Compare the deployed binary checksum with a freshly built one to confirm corruption.
  3. Regenerate the embedded obfuscator wasm asset with the project build tooling.
  4. If reproducible in a clean build, report upstream with the wrapped gzip error.
Defensive patterns

Strategy: try-catch

Validate before calling

// Decompress fully in a test to detect truncation
if _, err := io.ReadAll(mustGzipReader(obfuscatorWasmGz)); err != nil {
    t.Fatalf("embedded wasm truncated: %v", err)
}

Try / catch

if _, err := io.ReadAll(zr); err != nil { return fmt.Errorf("failed to decompress obfuscator wasm: %w", err) }

Prevention

When it happens

Trigger: Calling NewChallengeRuntime/Configure when reading the decompressed obfuscatorWasmGz stream fails — truncated embedded asset, bit rot in the binary, or corrupted memory of the byte slice.

Common situations: Truncated binaries from interrupted downloads/deploys; corrupted embedded assets in a custom build; running a binary damaged by disk issues.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/e3589b4c9ff8e378. Report an issue: GitHub.