Skip to content

Persistent app-server and pid-update-loop disappear without restart, leaving stale daemon state on Linux #35295

Open

Description

@Nadr0j

What version of the Codex App are you using (From “About Codex” dialog)?

Remote Linux host is running standalone Codex CLI/app-server 0.145.0

What subscription do you have?

Pro

What platform is your computer?

Linux 6.12.63+deb13-amd64 x86_64 unknown

What issue are you seeing?

Summary

A persistent remote-control app-server on a Linux host stopped unexpectedly and was not restarted. Both the app-server and its managed pid-update-loop were absent afterward, leaving a stale control socket and
updater PID file. The host consequently became inaccessible from the ChatGPT mobile app.

This may be related to #23954, which reports managed-daemon PID instability and unexpected app-server replacement. This case differs because both managed processes disappeared and persistent mode did not recover
either one.

Environment

  • Remote host OS: Debian 13 (trixie)
  • Kernel: Linux 6.12.63+deb13-amd64 x86_64
  • Codex CLI/app-server: 0.145.0
  • Install method: standalone
  • Authentication: ChatGPT
  • Daemon mode: persistent
  • Remote Control: enabled
  • Remote client: ChatGPT mobile app

The daemon settings file still contained:

{
  "remoteControlEnabled": true
}

Actual behavior

Remote Control had been working from my phone. Later, the Linux host appeared offline and could no longer be accessed remotely.

codex doctor reported:

⚠ app-server   background server socket is stale or unreachable

daemon state dir         ~/.codex/app-server-daemon
settings                 ~/.codex/app-server-daemon/settings.json (file)
pid file                 ~/.codex/app-server-daemon/app-server.pid (missing)
update-loop pid file     ~/.codex/app-server-daemon/app-server-updater.pid (file)
control socket           ~/.codex/app-server-control/app-server-control.sock
status                   stale or unreachable
app-server version       unavailable (failed to connect to control socket)
mode                     persistent

Running the daemon version check produced:

$ codex app-server daemon version
Error: failed to connect to /home/<redacted>/.codex/app-server-control/app-server-control.sock

No codex app-server or codex app-server daemon pid-update-loop process remained.

The stale updater PID file contained a PID that no longer existed:

{
  "pid": 2167423,
  "processStartTime": "Fri Jul 24 15:35:29 2026"
}

The app-server stderr log ended abruptly at approximately 2026-07-24 20:55 PDT. It did not contain a panic, fatal application error, graceful shutdown, exit status, or terminating signal.

Host investigation

I checked the host for an external termination cause:

$ sudo journalctl --since "2026-07-24 20:45" \
    --until "2026-07-24 21:10" |
    grep -Ei 'oom|out of memory|killed process|codex|2167423|session|scope'

# No output

I also queried journald for the stale updater PID:

$ sudo journalctl _PID=2167423 --no-pager
-- No entries --

Additional findings:

  • The host did not reboot.
  • There was no logged OOM-killer event.
  • There was no relevant systemd or session shutdown event.
  • There was no core dump.
  • No Codex update was installed at the failure time.
  • Codex state and log database integrity checks passed.
  • The final stderr entries were recoverable tool or model-cache errors, not a panic.

Because neither Codex nor journald retained a termination record, the original exit trigger cannot be determined retrospectively.

What steps can reproduce the bug?

Reproduction

I do not yet have a deterministic trigger:

  1. Install standalone Codex on a Linux host.
  2. Enable Remote Control and persistent daemon mode.
  3. Confirm the host is accessible from ChatGPT mobile.
  4. Leave the app-server running during normal Codex activity.
  5. Eventually, the mobile host becomes unavailable.
  6. Observe that both managed processes are absent while the socket and updater PID file remain stale.

I can provide a redacted codex doctor --json report and the daemon stderr log if needed.

What is the expected behavior?

Expected behavior

When persistent mode and Remote Control are enabled:

  1. The managed updater loop should remain alive.
  2. If app-server exits, it should be restarted automatically.
  3. If the updater loop also exits, another supervision mechanism should recover it.
  4. Exit status, terminating signal, and restart failures should be persisted.
  5. Stale sockets and PID files should be detected and repaired automatically.

The host should not remain offline indefinitely with stale daemon state.

Additional information

No response

Activity

  1. added
    appIssues related to the Codex desktop app
    on Jul 25, 2026
  2. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    app-serverIssues involving app server protocol or interfaces
    on Jul 25, 2026
  3. github-actions commented on Jul 25, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  4. TusanHomichi commented on Aug 26, 2026

    @TusanHomichi

    I now have a deterministic reboot reproduction on standalone Codex CLI 0.149.1.

    Environment:

    • Ubuntu 26.04.1 LTS, kernel 7.0.0-30-generic, x86_64
    • standalone Codex CLI/app-server 0.149.1
    • pid-managed app-server with Remote Control enabled
    • lingering systemd user manager invokes codex app-server daemon bootstrap --remote-control at boot

    Before reboot, both managed processes were healthy. Their PID records persisted in ~/.codex/app-server-daemon/. After reboot, neither process existed, but bootstrap failed instead of classifying the previous-boot records as stale:

    Error: failed to read start time for pid-managed app server 1902
    

    The stale record was:

    {"pid":1902,"processStartTime":"Wed Aug 26 10:25:14 2026"}

    The user service consequently remained failed and Remote Control stayed offline. The same stale state also makes the supported recovery commands fail:

    $ codex app-server daemon stop
    Error: failed to read start time for pid-managed app server 1902
    
    $ codex remote-control start --json
    Error: failed to read start time for pid-managed app server 1924
    

    Removing only the PID records whose process is absent (or whose live process start time differs from processStartTime) allows daemon bootstrap --remote-control to recreate both processes immediately. Both then report 0.149.1 and Remote Control connects.

    Expected behavior: every daemon subcommand that reads a PID record should treat an absent PID or a start-time mismatch as stale state, remove/reconcile that record under the daemon lock, and continue. Malformed records should still fail loudly. This should make boot recovery deterministic without an external preflight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIappIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingremote

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions