crowdsecurity/crowdsec · critical

failed to create wasm runtime in compiler mode: %v (the kern

Error message

failed to create wasm runtime in compiler mode: %v (the kernel likely denied an executable memory mapping: check W^X hardening, seccomp or SELinux policy)

What it means

wazero panics when it cannot allocate executable memory for its compiler runtime; newWazeroRuntime recovers the panic and returns this error. It means the kernel refused an executable mapping (W^X policy, seccomp, SELinux, or hardened sandbox), so compiler-mode WASM cannot start.

Source

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

	default:
		return fmt.Errorf("GOARCH %s has no wasm compiler backend", runtime.GOARCH)
	}
}

func newWazeroRuntime(ctx context.Context) (wazero.Runtime, error) {
	if err := compilerSupported(); err != nil {
		return nil, fmt.Errorf("wasm compiler mode unavailable: %w", err)
	}

	var r wazero.Runtime
	var err error

	func() {
		// wazero checks for executable memory, and panics if it cannot allocat it.
		// Catch the panic and return an error instead, so we can provide a more helpful message to the user.
		defer func() {
			if rec := recover(); rec != nil {
				err = fmt.Errorf("failed to create wasm runtime in compiler mode: %v "+
					"(the kernel likely denied an executable memory mapping: check W^X hardening, seccomp or SELinux policy)", rec)
			}
		}()

		r = wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigCompiler())
	}()

	if err != nil {
		return nil, err
	}

	return r, nil
}

func NewChallengeRuntime(ctx context.Context, opts ...Option) (*ChallengeRuntime, error) {
	resolvedOpts := runtimeOptions{}
	for _, opt := range opts {
		opt(&resolvedOpts)

View on GitHub (pinned to 909b515798)

Solutions

  1. Allow executable memory for the crowdsec process: adjust seccomp profile (allow mmap/mprotect with PROT_EXEC) or set the container to unconfined seccomp.
  2. Adjust SELinux policy (e.g. set enforcement to permissive for testing, or add a module allowing execmem for crowdsec).
  3. Run the container with a securityContext that permits execmem, or on hosts where W^X hardening can be relaxed for this process.
  4. If policy cannot be changed, request/request upstream support for interpreter mode which does not need exec memory.

Example fix

// docker run before/after
// before
docker run crowdsec/crowdsec
// after
docker run --security-opt seccomp=unconfined crowdsec/crowdsec # or a profile allowing execmem
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check execmem capability (Linux): attempt a PROT_EXEC mapping in your install script
// Or check container seccomp/SELinux policy before deploying appsec

Try / catch

err := initChallengeRuntime()
if err != nil && strings.Contains(err.Error(), "executable memory mapping") {
    // fall back: run without appsec challenge, or fix policy (seccomp=unconfined / SELinux permissive) and retry
}

Prevention

When it happens

Trigger: NewChallengeRuntime -> newWazeroRuntime -> wazero.NewRuntimeWithConfig(NewRuntimeConfigCompiler()) panics because mmap with PROT_EXEC is denied by seccomp, SELinux/AppArmor, gVisor, OpenBSD W^X, or container runtimes that disallow execmem.

Common situations: Docker with default seccomp in hardened setups, Kubernetes pods with restricted policies, SELinux enforcing on RHEL, gVisor/Kata sandboxes, shared hosting with noexec memory rules.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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