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

  1. 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.
  2. 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.
  3. Check for noexec: run `mount | grep noexec` against the directory holding createdump; if present, move the runtime tree or remount exec.
  4. Point DOTNET_DbgCreateDumpToolPath at a known-good, executable createdump directory and re-run.
  5. 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

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


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/549b90531152b1a6. Report an issue: GitHub.