{"record":{"id":"d69d7ff37a5bfd8d","repo":"basecamp/kamal","slug":"otel-endpoint-is-required","errorCode":null,"errorMessage":"OTel endpoint is required","messagePattern":"OTel endpoint is required","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/kamal/output/otel_logger.rb","lineNumber":3,"sourceCode":"class Kamal::Output::OtelLogger < Kamal::Output::BaseLogger\n  def self.build(settings:, config:)\n    raise ArgumentError, \"OTel endpoint is required\" unless settings[\"endpoint\"]\n    new(\n      endpoint: settings[\"endpoint\"],\n      tags: Kamal::Tags.from_config(config).except(:service_version, :recorded_at),\n      service: config.service\n    )\n  end\n\n  def initialize(endpoint:, tags:, service: nil)\n    @endpoint = endpoint\n    @shipper = Kamal::OtelShipper.new(endpoint: endpoint, tags: tags)\n    @service = service\n    super()\n  end\n\n  def <<(message)\n    host = Thread.current[:kamal_host]\n    iostream = Thread.current[:kamal_iostream]\n    severity = Thread.current[:kamal_severity]","sourceCodeStart":1,"sourceCodeEnd":21,"githubUrl":"https://github.com/basecamp/kamal/blob/eee0083b38661c3707c6b6052cc89e85038a096c/lib/kamal/output/otel_logger.rb#L1-L21","documentation":"Kamal raises ArgumentError \"OTel endpoint is required\" when output.otel is configured in deploy.yml without an endpoint setting. OtelLogger.build (lib/kamal/output/otel_logger.rb:3) requires settings[\"endpoint\"] and constructs a Kamal::OtelShipper that POSTs logs to that OpenTelemetry OTLP HTTP endpoint.","triggerScenarios":"deploy.yml containing output: otel: with an empty/null value or a mapping lacking endpoint. The logger is built at config load time (Kamal::Configuration::Output#build_loggers), so every kamal command fails until fixed.","commonSituations":"Adding otel: as a stub while setting up observability; forgetting that the collector URL (e.g. http://localhost:4318/v1/logs) is mandatory; copy-paste from docs that omitted the endpoint line.","solutions":["Add endpoint: under otel: pointing at your OTLP HTTP endpoint, e.g. http://localhost:4318/v1/logs","Verify the collector accepts OTLP/HTTP on that port (4318 is the standard) and is reachable from the machine running kamal","Remove the output: otel: entry if you did not intend to ship logs"],"exampleFix":"# deploy.yml (before)\noutput:\n  otel:\n\n# deploy.yml (after)\noutput:\n  otel:\n    endpoint: http://localhost:4318/v1/logs","handlingStrategy":"validation","validationCode":"require \"yaml\"\n\nconfig = YAML.load_file(\"config/deploy.yml\", aliases: true)\notel = config.dig(\"output\", \"otel\")\nif !otel.nil? && otel.to_h[\"endpoint\"].to_s.empty?\n  abort \"output.otel requires an endpoint setting\"\nend","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure a local OTLP collector first (e.g. otelcol on :4318) and point endpoint at it","Treat endpoint as mandatory whenever output.otel is present; no stubs in committed config"],"tags":["kamal","logging","opentelemetry","configuration","observability"],"backgroundTag":"missing-required-config-key","analyzedSha":"eee0083b38661c3707c6b6052cc89e85038a096c","analyzedAt":"2026-08-21T15:17:22.045Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}