{"record":{"id":"1980c532b240a639","repo":"basecamp/kamal","slug":"failed-to-get-endpoint-for-role-on-host-did-1980c5","errorCode":null,"errorMessage":"Failed to get endpoint for #{role} on #{host}, did the container boot?","messagePattern":"Failed to get endpoint for #(.+?) on #(.+?), did the container boot\\?","errorType":"exception","errorClass":"Kamal::Cli::BootError","httpStatus":null,"severity":"critical","filePath":"lib/kamal/cli/app/boot.rb","lineNumber":56,"sourceCode":"        info \"Renaming container #{version} to #{renamed_version} as already deployed on #{host}\"\n        audit(\"Renaming container #{version} to #{renamed_version}\")\n        execute *app.rename_container(version: version, new_version: renamed_version)\n      end\n\n      capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip.presence\n    end\n\n    def start_new_version\n      audit \"Booted app version #{version}\"\n      hostname = \"#{host.to_s[0...51].chomp(\".\")}-#{SecureRandom.hex(6)}\"\n\n      execute *app.ensure_env_directory\n      upload! role.secrets_io(host), role.secrets_path, mode: \"0600\"\n\n      execute *app.run(hostname: hostname)\n      if running_proxy?\n        endpoint = capture_with_info(*app.container_id_for_version(version)).strip\n        raise Kamal::Cli::BootError, \"Failed to get endpoint for #{role} on #{host}, did the container boot?\" if endpoint.empty?\n        execute *app.deploy(target: endpoint)\n      else\n        Kamal::Cli::Healthcheck::Poller.wait_for_healthy { capture_with_info(*app.status(version: version)) }\n      end\n    rescue => e\n      error \"Failed to boot #{role} on #{host}\"\n      raise e\n    end\n\n    def stop_new_version\n      execute *app.stop(version: version), raise_on_non_zero_exit: false\n    end\n\n    def stop_old_version(version)\n      execute *app.stop(version: version), raise_on_non_zero_exit: false\n      execute *app.clean_up_assets if assets?\n      execute *app.clean_up_error_pages if KAMAL.config.error_pages_path\n    end","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/basecamp/kamal/blob/eee0083b38661c3707c6b6052cc89e85038a096c/lib/kamal/cli/app/boot.rb#L38-L74","documentation":"During `kamal deploy`, Kamal::Cli::App::Boot#start_new_version uploads secrets, runs the new app container, and — for roles configured with proxy: true — must find the new container id to register it as the proxy's traffic endpoint. It captures `app.container_id_for_version(version)`; if that returns an empty string, the freshly run container is not running (it exited or failed to start), so Kamal raises Kamal::Cli::BootError, logs 'Failed to boot <role> on <host>', and the deploy aborts before old containers are stopped.","triggerScenarios":"`kamal deploy` (or `kamal app boot`) on a role with running_proxy? true where `docker run` succeeded as a command but the container immediately exits: bad entrypoint, missing secret file uploaded with wrong content, crashed process, missing image on the host, or a name/hostname collision. The rescue block re-raises after logging, failing the whole deploy.","commonSituations":"First deploy of a role whose image entrypoint references a missing env var; secrets template renders empty so the app raises on boot; role uses kamal proxy labels but container port is wrong; host out of disk so docker run fails silently; stale docker images after a registry migration.","solutions":["Get the boot failure details: `kamal app logs -r <role> -h <host>` (the error message names the role and host) — fix the crash shown there.","Reproduce on the host: ssh in and run `docker ps -a --filter name=<service>-<version>` then `docker logs <id>` to see the exact exit reason.","Check the role's secrets/env for the destination (`kamal app secrets` style inspection) and confirm the secrets file exists with mode 0600 on the host.","After fixing, re-run `kamal deploy`; the failed new version is stopped by stop_new_version, so old version keeps serving.","If the image itself is broken, roll back the build: redeploy a previous version with `kamal deploy --version <old>` or fix and push a new image."],"exampleFix":"# before: deploy fails with BootError, container exits instantly\nkamal deploy\n# after: diagnose the exited container on the failing host first\nkamal app logs -r web -h 203.0.113.10\nssh app@203.0.113.10 'docker ps -a --filter name=myapp- | head; docker logs $(docker ps -aq --filter name=myapp- | head -1)'\n# fix entrypoint/secrets in config, then:\nkamal deploy","handlingStrategy":"try-catch","validationCode":"# Smoke-test bootability before deploying: run the image locally with the same env\n# docker run --rm --env-file .kamal/secrets.<role> <image> <entrypoint> --check || echo 'will fail boot'","typeGuard":"def image_boots?(image, env = {})\n  env_args = env.map { |k, v| \"-e #{k}=#{v}\" }.join(\" \")\n  system(\"docker run --rm #{env_args} #{image} true\")\nend","tryCatchPattern":"begin\n  Kamal::CLI::Deploy.new.perform # wraps App::Boot#start_new_version\nrescue Kamal::Cli::BootError => e\n  warn \"boot failed: #{e.message} — old version still serving\"\n  `kamal app logs -r #{role}` # gather evidence; deploy already stopped the bad version\n  raise\nend","preventionTips":["Add a Docker HEALTHCHECK and boot smoke test so a crash-looping image fails in CI, not on hosts.","Render and inspect secrets for each role/destination before deploying (`kamal app secrets` equivalents).","Watch `docker events`/logs on first deploy of a new role to catch immediate exits early."],"tags":["kamal","deploy","boot","proxy","container","docker"],"backgroundTag":"container-failed-to-start","analyzedSha":"eee0083b38661c3707c6b6052cc89e85038a096c","analyzedAt":"2026-08-21T15:17:22.045Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}