dotnet/runtime · error

Problem launching createdump (may not have execute permissio

Error message

Problem launching createdump (may not have execute permissions): execve(%s) FAILED %s (%d)\n

What it means

Emitted by the forked child in PROCLaunchCreateDump (process.cpp:1560). This is the `else` branch taken only when g_createdumpCallback is nullptr (i.e. the runtime was NOT built to use a statically-linked createdump), so the child must execve(argv[0], argv, palEnvironment) an external createdump binary. Unlike the NativeAOT sibling (error 240), the PAL does NOT special-case ENOENT, so a missing binary, a non-executable binary, a noexec mount, a wrong-architecture binary, or arg-list overflow ALL surface through this single message. On failure the child exit(-1).

Source

Thrown at src/coreclr/pal/src/thread/process.cpp:1560

            // Call the statically linked createdump code
            int argc = 0;
            while (argv[argc] != nullptr && argc < MAX_ARGV_ENTRIES)
            {
                argc++;
            }
            callbackResult = g_createdumpCallback(argc, argv);
            // Set the shutdown callback to nullptr and exit
            // If we don't exit, the child's execution will continue into the diagnostic server behavior
            // which causes all sorts of problems.
            g_shutdownCallback = nullptr;
            exit(callbackResult);
        }
        else
        {
            // Execute the createdump program
            if (execve(argv[0], (char**)argv, palEnvironment) == -1)
            {
                fprintf(stderr, "Problem launching createdump (may not have execute permissions): execve(%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.
            ERROR("PROCCreateCrashDump: prctl() FAILED %s (%d)\n", strerror(errno), errno);
        }
#endif // HAVE_PRCTL_H && HAVE_PR_SET_PTRACER
        // Signal child that prctl(PR_SET_PTRACER, childpid) is done

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Locate createdump for your runtime: `find / -name createdump 2>/dev/null` and verify it is in the same directory as libcoreclr.so; reinstall/restore the runtime package if absent.
  2. Ensure the executable bit: `chmod +x <dir>/createdump` and that the owning user can traverse and execute it.
  3. Confirm the binary matches the process architecture (file <dir>/createdump) — a wrong ELF class yields ENOEXEC.
  4. Check for noexec on the runtime mount: `mount | grep noexec`; relocate the runtime or remount exec.
  5. If you cannot ship an external createdump, build/use a runtime with the statically-linked createdump callback (g_createdumpCallback) so the forked child calls it in-process instead of execve, or disable minidumps and use the OS core pattern.

Example fix

# before: createdump missing from a stripped base image
$ DOTNET_DbgEnableMiniDump=1 ./app
# Problem launching createdump: execve(/usr/share/dotnet/createdump) FAILED No such file (2)

# after: restore createdump from the runtime package
$ ls /usr/share/dotnet/createdump || cp createdump /usr/share/dotnet/ && chmod +x /usr/share/dotnet/createdump
$ DOTNET_DbgEnableMiniDump=1 ./app
Defensive patterns

Strategy: validation

Validate before calling

# Validate the external createdump binary the CoreCLR PAL will execve before enabling minidumps.
RT=$(dirname "$(readlink -f "$(command -v dotnet 2>/dev/null)")/shared"); 
BIN=$(find / -name createdump 2>/dev/null | head -n1)
[ -n "$BIN" ] || { echo 'createdump not found; reinstall the runtime package'; exit 1; }
[ -x "$BIN" ] || { chmod +x "$BIN" || { echo "cannot chmod $BIN"; exit 1; }; }
file "$BIN" | grep -qi "$(uname -m)" || { echo 'createdump wrong arch'; exit 1; }
export DOTNET_DbgEnableMiniDump=1
exec "$@"

Prevention

When it happens

Trigger: The full CoreCLR runtime (not NativeAOT) is configured to write dumps on crash (DOTNET_DbgEnableMiniDump=1, or a DOTNET_DbgMiniDumpType, or invoked by the diagnostics server), g_createdumpCallback is unset, and the child's execve of the createdump path fails. The path comes from the runtime layout next to libcoreclr.so or from DOTNET_DbgCreateDumpToolPath.

Common situations: createdump binary missing from the installed runtime (partial/custom .NET install, docker image that stripped createdump, single-file app where createdump is not extracted); createdump present but without +x or on a noexec mount; wrong-arch createdump after a multiarch copy; SELinux/AppArmor denying execve; E2BIG from an extremely long dump name/path; binfmt misconfiguration returning ENOEXEC.

Related errors


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