{"record":{"id":"0a212dd4cf709ca1","repo":"coollabsio/coolify","slug":"command-execution-failed-exit-code-process-resu","errorCode":null,"errorMessage":"Command execution failed (exit code {$process_result->exitCode()}): {$redactedCommand}\nError: {$error}","messagePattern":"Command execution failed \\(exit code (.+?)\\): (.+?)\nError: (.+?)","errorType":"exception","errorClass":"DeploymentException","httpStatus":null,"severity":"error","filePath":"app/Traits/ExecuteRemoteCommand.php","lineNumber":243,"sourceCode":"        $process_result = $process->wait();\n        if ($process_result->exitCode() !== 0) {\n            if (! $ignore_errors) {\n                // Check if deployment was cancelled while command was running\n                if (isset($this->application_deployment_queue)) {\n                    $this->application_deployment_queue->refresh();\n                    if ($this->application_deployment_queue->status === ApplicationDeploymentStatus::CANCELLED_BY_USER->value) {\n                        throw new \\RuntimeException('Deployment cancelled by user', 69420);\n                    }\n                }\n\n                // Don't immediately set to FAILED - let the retry logic handle it\n                // This prevents premature status changes during retryable SSH errors\n                $error = $process_result->errorOutput();\n                if (empty($error)) {\n                    $error = $process_result->output() ?: 'Command failed with no error output';\n                }\n                $redactedCommand = $this->redact_sensitive_info($command);\n                throw new DeploymentException(\"Command execution failed (exit code {$process_result->exitCode()}): {$redactedCommand}\\nError: {$error}\");\n            }\n        }\n    }\n\n    /**\n     * Add a log entry for SSH retry attempts\n     */\n    private function addRetryLogEntry(int $attempt, int $maxRetries, int $delay, string $errorMessage)\n    {\n        $retryMessage = \"SSH connection failed. Retrying... (Attempt {$attempt}/{$maxRetries}, waiting {$delay}s)\\nError: {$errorMessage}\";\n\n        $new_log_entry = [\n            'output' => $this->redact_sensitive_info($retryMessage),\n            'type' => 'stdout',\n            'timestamp' => Carbon::now('UTC'),\n            'hidden' => false,\n            'batch' => static::$batch_counter,\n        ];","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Traits/ExecuteRemoteCommand.php#L225-L261","documentation":"Coolify runs every deployment step over SSH on the destination server via the ExecuteRemoteCommand trait (Symfony Process wrapping an SSH multiplexed command). When the process finishes with a non-zero exit code and ignore_errors is false, it throws DeploymentException containing the exit code, the command with secrets redacted via redact_sensitive_info(), and the stderr output (falling back to stdout, then to 'Command failed with no error output'). ApplicationDeploymentJob catches it, marks the deployment queue row as failed, and preserves the logs. A special exit code 69420 instead means 'Deployment cancelled by user'.","triggerScenarios":"Any deployment command that exits non-zero: git clone/pull failing on a missing branch, missing deploy key or expired token; docker build failing on a bad Dockerfile or unpullable base image; docker compose up failing; a run command in the build pack exiting non-zero; the destination server having a full disk or a stopped Docker daemon.","commonSituations":"Private repo without a working deploy key; typo'd branch/tag or image tag; missing build arg or environment variable used during build; registry rate limits or network problems on the server; disk exhausted so layers cannot be written; server Docker daemon down while SSH itself still works.","solutions":["Open the deployment logs and read the 'Error:' section under the failing command — it is the command's stderr and names the root cause.","SSH into the destination server and re-run the redacted command shown in the message to reproduce the failure interactively.","Check server health: df -h for disk space, docker ps to confirm the daemon, and curl to the registry from the server.","For git failures, verify the branch/tag exists and that the deploy key/token still has access to the repository.","Fix the underlying cause (Dockerfile, build pack command, env vars) and redeploy; transient SSH errors are retried automatically by the SSH retry logic before this exception surfaces."],"exampleFix":"// before: deployment fails with\n// Command execution failed (exit code 1): git clone -b $branch ... \n// Error: Remote branch main not found in upstream origin\n// after: point the application at a branch that exists, then redeploy\n$application->update(['git_branch' => 'master']);\n$application->deploy();","handlingStrategy":"try-catch","validationCode":"// Pre-flight the destination server before triggering a deployment\nuse App\\Models\\Server;\n$server = Server::findOrFail($destination->server_id);\ninstant_remote_process(['docker info >/dev/null && df -h / | tail -1'], $server);\n// throws early with a clearer error than a mid-deploy failure","typeGuard":null,"tryCatchPattern":"try {\n    $application->deploy();\n} catch (\\App\\Exceptions\\DeploymentException $e) {\n    // message contains exit code, redacted command, and stderr\n    report($e);\n    // mark the attempt failed in your tracker; keep deployment logs for triage\n}","preventionTips":["Build and run the Dockerfile locally before pushing so exit-code surprises surface before deploy","Keep deploy keys/tokens valid and scoped; rotate before expiry","Monitor disk space on destination servers — full disks are a classic non-zero exit source","Pin base image tags and registry credentials to avoid pull-time failures"],"tags":["deployment","ssh","docker","exit-code","remote-command"],"backgroundTag":"non-zero-exit-code","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}