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 modeView on GitHub (pinned to 909b515798)
Solutions
- Rebuild and redeploy the crowdsec binary from a clean source tree (make build).
- Compare the deployed binary checksum with a freshly built one to confirm corruption.
- Regenerate the embedded obfuscator wasm asset with the project build tooling.
- 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
- Compare deployed binary checksums against CI artifacts after deploys
- Add a test decompressing the embedded wasm end-to-end
- Avoid post-build binary mangling (strip/patch scripts that can truncate)
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
- failed to create gzip reader for obfuscator wasm: %w
- failed to read gz %s: %w
- failed to compile obfuscator wasm module: %w
- GOARCH %s has no wasm compiler backend
- wasm compiler mode unavailable: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/e3589b4c9ff8e378.
Report an issue: GitHub.