dotnet/runtime · error
Problem launching createdump (may not have execute permissio
Error message
Problem launching createdump (may not have execute permissions): execv(%s) FAILED %s (%d)\n
What it means
Emitted by the NativeAOT crash-dump helper in CreateCrashDump (PalCreateDump.cpp:277). After fork(), the child first blocks reading a one-byte prctl(PR_SET_PTRACER) signal from the parent, then calls execv() on g_szCreateDumpPath to overlay itself with the createdump utility. This fprintf fires when execv() returns -1 with an errno OTHER than ENOENT (ENOENT has its own message at line 273), i.e. the path resolved but the kernel refused to execute it; the child then exit(-1) and no core dump is written. The 'may not have execute permissions' text points at EACCES, but ENOEXEC, E2BIG and ENOMEM reach this same branch.
Source
Thrown at src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp:277
close(child_write_pipe);
exit(-1);
}
// Only dup the child's stderr if there is error buffer
if (errorMessageBuffer != nullptr)
{
dup2(child_write_pipe, STDERR_FILENO);
}
// Execute the createdump program
if (execv(argv[0], (char* const *)argv) == -1)
{
if (errno == ENOENT)
{
fprintf(stderr, "DOTNET_DbgEnableMiniDump is set and the createdump binary does not exist: %s\n", argv[0]);
}
else
{
fprintf(stderr, "Problem launching createdump (may not have execute permissions): execv(%s) FAILED %s (%d)\n", argv[0], strerror(errno), errno);
}
exit(-1);
}
}
else
{
close(child_read_pipe);
close(child_write_pipe);
#if HAVE_PRCTL_H && HAVE_PR_SET_PTRACER
// Gives the child process permission to use /proc/<pid>/mem and ptrace
if (prctl(PR_SET_PTRACER, childpid, 0, 0, 0) == -1)
{
// Ignore any error because on some CentOS and OpenSUSE distros, it isn't
// supported but createdump works just fine.
#ifdef _DEBUG
fprintf(stderr, "CreateCrashDump: prctl() FAILED %s (%d)\n", strerror(errno), errno);
#endif
}View on GitHub (pinned to 290d5ab72c)
Solutions
- Resolve the exact path the runtime uses (echo $DOTNET_DbgCreateDumpToolPath, or the directory of libcoreclr.so) and run `ls -l <dir>/createdump`; fix the mode with chmod +x if missing.
- If createdump is absent, repair your publish/copy pipeline so it ships next to the native runtime library; for trimmed/single-file NativeAOT scenarios verify createdump was not excluded.
- Check for noexec: run `mount | grep noexec` against the directory holding createdump; if present, move the runtime tree or remount exec.
- Point DOTNET_DbgCreateDumpToolPath at a known-good, executable createdump directory and re-run.
- On RHEL/CentOS/SuSE with SELinux, inspect `ausearch -m AVC -ts recent` for EXEC denials on createdump and adjust policy/labels.
Example fix
# before: createdump has no exec bit $ ls -l /opt/app/createdump -rw-r--r-- 1 app app 123456 createdump # DOTNET_DbgEnableMiniDump=1 ./app -> execv FAILED Permission denied (13) # after $ chmod +x /opt/app/createdump $ DOTNET_DbgEnableMiniDump=1 DOTNET_DbgCreateDumpToolPath=/opt/app ./app
Defensive patterns
Strategy: validation
Validate before calling
# Validate the createdump binary the NativeAOT runtime will execv before enabling dumps.
DIR="${DOTNET_DbgCreateDumpToolPath:-$(dirname "$(find / -name 'libcoreclr*' 2>/dev/null | head -n1)")"
BIN="$DIR/createdump"
[ -x "$BIN" ] || { echo "createdump missing or not executable: $BIN"; exit 1; }
file "$BIN" | grep -qi "$(uname -m)" || { echo "createdump wrong arch"; exit 1; }
mount | grep -q " $(df "$DIR" --output=mountpoint | tail -n1) .*noexec" && { echo "noexec mount"; exit 1; }
export DOTNET_DbgEnableMiniDump=1
exec "$@" Prevention
- Always publish/copy createdump next to the native runtime library and preserve the executable bit (use cp -p or a tarball that stores mode).
- Never place the runtime on a noexec mount in containers; verify with `mount | grep noexec`.
- For NativeAOT, set DOTNET_DbgCreateDumpToolPath explicitly to a directory you control rather than relying on dladdr-derived discovery.
- Add a pre-launch check in your container entrypoint that `[ -x ]` the createdump binary before enabling DOTNET_DbgEnableMiniDump.
- Keep createdump architecture-aligned with the process; verify with `file createdump`.
When it happens
Trigger: A NativeAOT-published process launched with DOTNET_DbgEnableMiniDump=1 (the DbgEnableMiniDump runtimeconfig key) encounters an unhandled crash; PalCreateCrashDumpIfEnabled() forks and the child reaches execv(argv[0]). argv[0] is g_szCreateDumpPath, computed in PalCreateDumpInitialize() either from DOTNET_DbgCreateDumpToolPATH concatenated with 'createdump', or from the directory of the CoreCLR native library discovered via dladdr(&PalCreateDumpInitialize). execv fails with a non-ENOENT errno.
Common situations: createdump shipped without the executable bit (chmod stripped during a custom copy/publish step); the runtime directory sits on a noexec mount (/tmp noexec, hardened container images); a createdump built for the wrong architecture was copied in (cross-arch publish); SELinux/AppArmor denying exec_trans; a truncated or corrupt createdump binary (ENOEXEC); argument list overflow (E2BIG) from a pathologically long DOTNET_DbgMiniDumpName.
Related errors
- Problem writing to createdump parent_write_pipe: %s (%d)\n
- Problem waiting for createdump: waitpid() FAILED result %d w
- Problem reading from createdump child_read_pipe: %s (%d)\n
- Problem launching createdump (may not have execute permissio
- Problem writing to createdump parent_write_pipe: %s (%d)\n
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/549b90531152b1a6.
Report an issue: GitHub.