basecamp/kamal · error · ArgumentError

OTel endpoint is required

Error message

OTel endpoint is required

What it means

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.

Source

Thrown at lib/kamal/output/otel_logger.rb:3

class Kamal::Output::OtelLogger < Kamal::Output::BaseLogger
  def self.build(settings:, config:)
    raise ArgumentError, "OTel endpoint is required" unless settings["endpoint"]
    new(
      endpoint: settings["endpoint"],
      tags: Kamal::Tags.from_config(config).except(:service_version, :recorded_at),
      service: config.service
    )
  end

  def initialize(endpoint:, tags:, service: nil)
    @endpoint = endpoint
    @shipper = Kamal::OtelShipper.new(endpoint: endpoint, tags: tags)
    @service = service
    super()
  end

  def <<(message)
    host = Thread.current[:kamal_host]
    iostream = Thread.current[:kamal_iostream]
    severity = Thread.current[:kamal_severity]

View on GitHub (pinned to eee0083b38)

Solutions

  1. Add endpoint: under otel: pointing at your OTLP HTTP endpoint, e.g. http://localhost:4318/v1/logs
  2. Verify the collector accepts OTLP/HTTP on that port (4318 is the standard) and is reachable from the machine running kamal
  3. Remove the output: otel: entry if you did not intend to ship logs

Example fix

# deploy.yml (before)
output:
  otel:

# deploy.yml (after)
output:
  otel:
    endpoint: http://localhost:4318/v1/logs
Defensive patterns

Strategy: validation

Validate before calling

require "yaml"

config = YAML.load_file("config/deploy.yml", aliases: true)
otel = config.dig("output", "otel")
if !otel.nil? && otel.to_h["endpoint"].to_s.empty?
  abort "output.otel requires an endpoint setting"
end

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21). Data as JSON: /api/errors/d69d7ff37a5bfd8d. Report an issue: GitHub.