dotnet/runtime · error
Problem writing to createdump parent_write_pipe: %s (%d)\n
Error message
Problem writing to createdump parent_write_pipe: %s (%d)\n
What it means
Emitted from the NativeAOT parent process in CreateCrashDump (PalCreateDump.cpp:304). After fork, the parent runs prctl(PR_SET_PTRACER, childpid) then writes a single 'S' byte through parent_write_pipe to release the child from its blocking read(); the write() is retried only on EINTR. If the final byte count is not 1 the parent prints this message, clears the error buffer, closes parent_read_pipe and returns false, so no dump is produced. The near-universal cause is a broken pipe: the child has already exited and closed its read end, so write() returns -1 with EPIPE.
Source
Thrown at src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp:304
#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
}
#endif // HAVE_PRCTL_H && HAVE_PR_SET_PTRACER
// Signal child that prctl(PR_SET_PTRACER, childpid) is done
int bytesWritten;
while((bytesWritten = write(parent_write_pipe, "S", 1)) < 0 && errno == EINTR);
close(parent_write_pipe);
if (bytesWritten != 1)
{
fprintf(stderr, "Problem writing to createdump parent_write_pipe: %s (%d)\n", strerror(errno), errno);
close(parent_read_pipe);
if (errorMessageBuffer != nullptr)
{
errorMessageBuffer[0] = 0;
}
return false;
}
// Read createdump's stderr messages (if any)
if (errorMessageBuffer != nullptr)
{
// Read createdump's stderr
int bytesRead = 0;
int count = 0;
while ((count = read(parent_read_pipe, errorMessageBuffer + bytesRead, cbErrorMessageBuffer - bytesRead)) > 0)
{
bytesRead += count;
}View on GitHub (pinned to 290d5ab72c)
Solutions
- Collect full createdump diagnostics first: set DOTNET_CreateDumpDiagnostics=1 and DOTNET_CreateDumpVerboseDiagnostics=1 and reproduce; the child's earlier 'Problem reading ... child_read_pipe' line is the real root cause.
- Check whether the process is being killed externally during crash handling (dmesg for oom-killer, container runtime OOM events) and raise memory limits or disable the reaper.
- Ensure no third-party SIGCHLD handler / init system (e.g. dumb-init, tini in PID-1 reap mode) is reaping the createdump child before the parent writes.
- Raise the open-files limit (ulimit -n) if the crash path is running out of pipe fds.
- If the environment cannot support out-of-proc dumps, unset DOTNET_DbgEnableMiniDump and rely on the OS core pattern (coredumpd/apport) instead.
Example fix
# before $ DOTNET_DbgEnableMiniDump=1 ./app # Problem writing to createdump parent_write_pipe: Broken pipe (32) # after: enable diagnostics to see the child's preceding failure $ DOTNET_DbgEnableMiniDump=1 \ DOTNET_CreateDumpDiagnostics=1 \ DOTNET_CreateDumpVerboseDiagnostics=1 \ ./app
Defensive patterns
Strategy: validation
Validate before calling
# Before relying on minidumps, verify the crash path can keep the parent/child pipe alive. [ "$(ulimit -n)" -ge 1024 ] || ulimit -n 65536 # Ensure no PID-1 reaper will steal or kill the child; if using --init, test dump capture once: DOTNET_DbgEnableMiniDump=1 DOTNET_CreateDumpVerboseDiagnostics=1 ./app & sleep 1; kill -ABRT $!; wait $! ls -l *.dmp 2>/dev/null || echo "WARN: dump handshake unreliable in this environment"
Prevention
- Always enable DOTNET_CreateDumpDiagnostics=1 / DOTNET_CreateDumpVerboseDiagnostics=1 during dump-path validation so the real upstream failure (usually the child_read_pipe read) is visible.
- Do not run under an aggressive PID-1 child reaper when minidumps are required.
- Raise ulimit -n and cgroup memory limits so the crash path has the fds/memory for the pipe handshake.
- Prefer the OS core_pattern for production crash capture and treat DOTNET_DbgEnableMiniDump as a secondary mechanism.
When it happens
Trigger: DOTNET_DbgEnableMiniDump=1 is set and the process crashes; the forked child dies during setup (for example it hit the 'Problem reading from createdump child_read_pipe' branch at line 258 and called exit(-1)) before the parent's write() completes. It can also fire if the parent itself is interrupted (signal) such that the write returns 0 or a non-EINTR error, or if the pipe fds were invalidated.
Common situations: Child perished first because the child_read_pipe read failed (parent never wrote, or parent died in the prctl path); the process was SIGKILLed by the OOM killer or a container reaper between fork and the parent's write; a custom SIGCHLD reaper or signal handler interfered; resource exhaustion (fd limit) left the pipe half-open.
Related errors
- Problem launching createdump (may not have execute permissio
- Problem waiting for createdump: waitpid() FAILED result %d w
- Problem reading from createdump child_read_pipe: %s (%d)\n
- Problem writing to createdump parent_write_pipe: %s (%d)\n
- Problem launching createdump (may not have execute permissio
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/6e437190cd983f3d.
Report an issue: GitHub.