# Troubleshooting Use this guide with [configuration](config.md) and [operations](operations.md). Messages are emitted through the standard logger on stderr. ## `config load failed: ... read "config.yml"` Symptom: startup exits before building sources or sinks. Likely cause: the process working directory does not contain `config.yml`, or the runtime user cannot read it. Diagnostic: run `pwd` in the same working directory used by the process, then check `ls -l config.yml`. Safe fix: place the intended config at `./config.yml`, change the working directory, or mount the file at `/weatherfeeder/config.yml` when using the provided container image. ## `config load failed: ... parse YAML` Symptom: startup exits with a YAML parse error or an unknown field error. Likely cause: invalid YAML syntax, multiple YAML documents, or a misspelled config struct field. Diagnostic: inspect the line and field in the error. Feedkit uses strict YAML field decoding for config struct fields. Safe fix: correct the YAML and compare the shape with [configuration](config.md). Driver-specific `params` keys are validated by their source or sink constructors. ## `config validation failed` Symptom: startup exits and prints one or more validation messages. Likely cause: missing `sources` or `sinks`, blank names, duplicate source or sink names, invalid `mode`, missing `every` for a polling source with `mode: poll`, or a route that references an unknown sink. Diagnostic: read every bullet under `config validation failed`; the loader sorts these messages so multiple issues can be fixed in one edit. Safe fix: update the top-level config fields as documented in [configuration](config.md). ## `unknown source driver` Symptom: startup exits with `build source failed`. Likely cause: `sources[].driver` does not match a registered weatherfeeder source driver. Diagnostic: compare the configured driver with the source driver table in [configuration](config.md#source-drivers). Safe fix: correct the driver name. Current drivers include `nws_observation`, `nws_alerts`, `nws_forecast_hourly`, `nws_forecast_narrative`, `nws_forecast_discussion`, `nws_weatherstories`, `openmeteo_observation`, `openmeteo_forecast`, `openweather_observation`, and `spc_convective_outlook`. ## `unknown sink driver` Symptom: startup exits with `build sink failed`. Likely cause: `sinks[].driver` is not registered. Diagnostic: compare the configured driver with the sink driver table in [configuration](config.md#sink-drivers). Safe fix: use `stdout`, `nats`, or `postgres`. ## `source expected kinds validation failed` Symptom: startup exits after building a source. Likely cause: `sources[].kinds` declares a kind the source does not emit. Diagnostic: compare the configured `kinds` list with the source driver kind in [configuration](config.md#source-drivers). Safe fix: remove `kinds` or set it to the kind emitted by that driver. ## `params.url is required` Or `params.user_agent is required` Symptom: startup exits with `build source failed`. Likely cause: a source is missing required HTTP params, or the values are blank or not strings. Diagnostic: inspect the named source in the error and check its `params`. Safe fix: add non-empty `url` and `user_agent` values. See [HTTP source params](config.md#http-source-params). SPC convective outlook sources do not use `params.url`; they require `latitude`, `longitude`, and `user_agent`. See [SPC convective outlook params](config.md#spc-convective-outlook-params). ## `params.latitude is required` Or `params.longitude is required` Symptom: startup exits for an `spc_convective_outlook` source. Likely cause: the source is missing one of the configured point coordinates. Diagnostic: inspect the named SPC source in the error and check its `params`. Safe fix: add numeric `latitude` and `longitude` values in decimal degrees. ## `url must include units=metric` Symptom: startup exits for an `openweather_observation` source. Likely cause: the OpenWeather URL omits `units=metric` or sets another unit system. Diagnostic: inspect the query string in `params.url`. Safe fix: add `units=metric` to the OpenWeather current-weather URL. Keep API keys out of committed configs. ## `source ... sources[].every must be > 0 for polling sources` Symptom: startup exits while building scheduler jobs. Likely cause: a current weatherfeeder polling source has no usable `every` interval. Diagnostic: inspect the named `sources[]` entry and check `every`. Safe fix: set a positive duration such as `1m`, `10m`, or `1h`. ## `build sink failed ... params.url is required` Symptom: startup exits while building a NATS sink. Likely cause: the NATS sink is missing `params.url`, or the value is blank or not a string. Diagnostic: inspect the named sink in the error and check its `params`. Safe fix: set a NATS URL such as `nats://localhost:4222`. ## `build sink failed ... params.subject is required` Symptom: startup exits while building a NATS sink. Likely cause: the NATS sink is missing `params.subject`, or the value is blank or not a string. Diagnostic: inspect the named sink in the error and check its `params`. Safe fix: set a non-empty subject such as `weatherfeeder`. ## `dispatch: sink ... failed consuming event ... NATS sink: connect` Symptom: the daemon starts, but NATS events are not published. Likely cause: the NATS server URL is unreachable, the server is not accepting connections, or the configured URL is wrong for the runtime network. Diagnostic: from the same runtime environment, check that the host and port in `sinks[].params.url` are reachable. Safe fix: correct the NATS URL or restore broker connectivity. Other configured sinks continue receiving events. ## `postgres sink ... open db` Symptom: startup exits while building a Postgres sink. Likely cause: the database URI, username, password, network path, or database availability is wrong. Diagnostic: inspect `sinks[].params.uri`, `username`, and `password`; verify that the same runtime environment can reach the database. Safe fix: correct the credentials or URI, restore database connectivity, then restart the daemon. ## `postgres sink ... ensure table` Or `ensure index` Symptom: startup exits during Postgres initialization. Likely cause: the database user cannot create required tables or indexes, an existing object conflicts with weatherfeeder's expected table contract, or the database is unavailable during initialization. Diagnostic: inspect the named table or index in the error and compare existing database objects with the [Postgres table contract](integrations/postgres.md). Safe fix: grant the needed database privileges, create a compatible schema, or perform an operator-managed migration before restarting. ## `postgres sink: insert into ...` Symptom: the daemon starts, but Postgres writes for some events fail. Likely cause: a duplicate primary key, incompatible existing table definition, database constraint error, or connection failure during a write transaction. Diagnostic: inspect the table name and database error in the log. Compare the table with [Postgres integration](integrations/postgres.md). Safe fix: repair the database schema or address the duplicate/connection issue. Other configured sinks continue receiving events. ## No Events Appear On A Sink Symptom: the daemon is running but the expected sink receives no events. Likely cause: the route does not match the event kind, the source has not emitted changed content, or the sink is failing per event. Diagnostic: check `routes`, source `kinds`, and logs for `scheduler: poll failed`, `dispatcher: pipeline error`, or `dispatch: sink ... failed consuming event`. Safe fix: correct the route or source configuration. If the source uses conditional HTTP and the upstream has not changed, no event is emitted for a `304 Not Modified` response; wait for changed upstream content or temporarily set `params.conditional: false` for diagnosis. ## `scheduler: poll failed` Symptom: one source logs poll failures while the daemon keeps running. Likely cause: upstream HTTP error, bad URL, timeout, response body limit, or provider response shape that the source cannot parse. Diagnostic: inspect the source name in the log and review its HTTP params. Safe fix: correct the URL, user agent, timeout, or body limit. The next scheduled poll will retry. ## `dispatcher: pipeline error` Symptom: source polling succeeds, but one event is dropped before sinks. Likely cause: a normalizer could not decode or map the raw payload, or dedupe received an invalid event ID. Diagnostic: inspect the error text and the source/schema that produced the event. Review the [event wire contract](integrations/events.md) for expected canonical fields. Safe fix: correct source configuration if it points to the wrong upstream product. If the upstream payload changed shape, update the relevant normalizer and tests.