Ishan Anilbhai Koradiya
02/24/2026, 4:28 PMkapa.ai
02/24/2026, 4:28 PMsourceStats.recordCount (the number of records associated with that state). If it’s missing or null, you get errors like:
• sourceStats must be set with recordCount for state message id=1
• or related exceptions such as State message does not contain id / NPEs when sourceStats is absent. [ClickHouse NPE; State id issue]
From the maintainer comment:
> “It is expected that a source will always populate the source stats attribute in a state message. The source stats is the count of records associated with the state message i.e. how many records the source has read that are associated with this given state message.” [ClickHouse NPE]
Given that:
• The problem is not specific to Postgres 3.0.6 itself, but to the state messages your source is emitting.
• This often shows up when using a custom source or a source that hasn’t been updated to the newer protocol expectations.
What you need to do
1. Check your source connector (especially if it’s custom or forked):
◦ For every STATE message it emits, ensure:
▪︎ state.sourceStats is present, and
▪︎ state.sourceStats.recordCount is a non-null number representing how many records were emitted since the previous state (or cumulatively, depending on your implementation, but it must be consistent).
2. Example of required fields in a state message (conceptually):
◦ AirbyteStateMessage must include:
▪︎ type (e.g., GLOBAL or STREAM)
▪︎ data / stream / global as appropriate
▪︎ sourceStats with recordCount set
3. If you are not maintaining the source:
◦ Share this error and the requirement above with the source’s maintainer; they need to update the connector to populate sourceStats.recordCount in all emitted state messages.
4. Until the source is fixed:
◦ Incremental syncs will not work reliably because Airbyte will refuse to persist state when sourceStats is missing or incomplete, leading to behavior like “Airbyte lost its cursor state” and repeated re-syncing. [ClickHouse bulk state]
The docs and issues do not show a Postgres-specific toggle to bypass this check; the fix must be in the source’s state emission logic. 👍 0 button 👎 0 button ℹ️ Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.Ishan Anilbhai Koradiya
02/24/2026, 4:31 PMkapa.ai
02/24/2026, 4:31 PMsourceStats
• sourceStats.recordCount must be set (number of records associated with that state)
There is a GitHub issue showing that when a source emits a state without sourceStats, destinations using the bulk CDK fail with a similar error / NPE. [ClickHouse NPE] Another issue shows that mismatches in these stats cause state reconciliation problems and duplicate processing. [Bulk state bug]
However, the provided knowledge sources do not say:
• From which version the Postgres source (like your 2.0.33) started populating sourceStats, or
• Whether 2.0.33 is guaranteed to be compatible with the newer bulk state expectations of Postgres destination 3.0.6.
So I cannot definitively say whether source-postgres 2.0.33 is compliant; the docs simply state the general requirement that sources must emit state and that state is used for checkpointing, but they don’t mention sourceStats or version compatibility details. [Protocol state; Protocol 2.0 state]
Given what we do know:
1. The destination is enforcing that sourceStats.recordCount be present.
This is consistent with the partner destination requirements and the ClickHouse issue. [Partner destinations; ClickHouse NPE]
2. Your error means the state messages from source-postgres 2.0.33 (for this connection) do not have sourceStats.recordCount set.
The destination then throws IllegalArgumentException: sourceStats must be set with recordCount for state message id=1.
Because the knowledge sources don’t include a fix or compatibility matrix, I can’t point you to an exact “upgrade to source version X” answer. What they do imply is:
• The correct fix is for the source to emit state messages with sourceStats.recordCount populated.
• This is a source-side change, not something you can toggle in the Postgres destination 3.0.6 configuration.
Practical next steps (based on available info):
• Confirm (via logs) that the state messages coming from your Postgres source indeed lack sourceStats or recordCount – this matches the pattern described in the ClickHouse issue. [ClickHouse NPE]
• If you control the source implementation (custom fork), it must be updated to populate sourceStats.recordCount on every emitted state.
• If you are using the standard source-postgres image and not modifying it, the knowledge sources do not say whether 2.0.33 is expected to support this; in that case, you’ll likely need to:
◦ Involve Airbyte support / open an issue referencing this error and the bulk state requirements, or
◦ Align both source and destination to versions that are known to work together (but the exact versions are not specified in the provided docs, so I cannot recommend a specific one from this context).
If you can share a snippet of the state messages from your job logs, that would help confirm that sourceStats.recordCount is missing, which is exactly what the destination is complaining about. 👍 0 button 👎 0 button ℹ️ Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.Ishan Anilbhai Koradiya
02/24/2026, 5:00 PMkapa.ai
02/24/2026, 5:00 PMCAST work that T+D used to do in your warehouse. [Direct load concept]
Table schema in Postgres (Direct Load)
For each stream, the final table contains your data columns plus Airbyte metadata columns: [Postgres schema map]
• _airbyte_raw_id (VARCHAR): unique id per record
• _airbyte_extracted_at (TIMESTAMPTZ): when the record was pulled from the source
• _airbyte_meta (JSONB): metadata about the record (including validation / schema-change info)
• _airbyte_generation_id (BIGINT): identifier for the sync generation
Data types are mapped from Airbyte types to Postgres types (e.g., string → VARCHAR, number → DECIMAL, object/array → JSONB, timestamps → appropriate `TIMESTAMP`/`TIME` types). [Postgres schema map]
Sync modes & visibility
With Direct Load: [What will change]
• Append: records are inserted directly into the target table as they are processed (they no longer “wait” in a raw table until the end of the sync).
• Dedup: for most destinations, records are written to a temporary table during the sync and periodically upserted into the final table; the temp table is dropped after a successful sync.
• Overwrite / refresh & remove: still use a temporary table to support no-downtime swaps, then replace the final table at the end.
Raw tables compatibility
If you still need raw tables:
• Enable “Raw tables only” on the Postgres destination. Then:
◦ Only raw tables are written (legacy behavior),
◦ Final tables are not created for that connection. [What will change; Postgres migration]
If you need both raw and final tables, you must use two destinations (one normal, one “Raw tables only”) and sync to both in parallel. [What will change; Postgres migration]
Schema evolution & errors
• Direct-load connectors apply schema changes via ALTER TABLE (or equivalent) instead of rebuilding tables via a soft reset. Some type changes can fail if historical data can’t be cast to the new type. [What will change]
• Type/serialization issues are recorded in _airbyte_meta with error reasons (now DESTINATION_SERIALIZATION_ERROR instead of the old T+D DESTINATION_TYPECAST_ERROR). [What will change]
In short: for Postgres 3.x, Direct Load means the connector itself casts and writes directly into final, typed tables with metadata columns, improving performance and eliminating persistent raw tables unless you explicitly opt into legacy raw-table mode. 👍 0 button 👎 0 button ℹ️ Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.Ishan Anilbhai Koradiya
02/24/2026, 7:04 PMkapa.ai
02/24/2026, 7:04 PM_airbyte_generation_id column on the logs table, but that column does not exist yet in Postgres.
With the move to Postgres destination 3.x and Direct Load, Airbyte changed the metadata columns on final tables:
• Old style: _airbyte_loaded_at
• New style: _airbyte_meta (JSONB) and _airbyte_generation_id (BIGINT) on the final tables [Postgres migration guide; Postgres schema map].
So this error typically means:
• Your existing logs table was created by an older (pre‑3.0.0) Postgres destination and does not yet have _airbyte_generation_id, but
• The upgraded 3.x destination is now trying to write to that table assuming the new schema (including _airbyte_generation_id).
The migration guide explicitly says that after upgrading you may need to adjust downstream objects and that final tables now include _airbyte_meta and _airbyte_generation_id instead of _airbyte_loaded_at. [Postgres migration guide]
What you can do (per docs):
• Let Airbyte recreate the table with the new schema by:
◦ Resetting the connection and re‑syncing, or
◦ Dropping the existing logs table so the destination can create it fresh with _airbyte_generation_id and _airbyte_meta.
• Also review any custom SQL / views that still expect the old _airbyte_loaded_at column and update them to the new metadata layout. [Postgres migration guide]
If you still see the error after a full reset (with the table recreated by Airbyte), then something outside the documented behavior is happening; the knowledge sources don’t provide more detail beyond the schema change itself. 👍 0 button 👎 0 button ℹ️ Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.Ishan Anilbhai Koradiya
02/24/2026, 8:02 PMkapa.ai
02/24/2026, 8:02 PMc.z.h.p.ProxyLeakTask(run):85 Connection leak detection triggered for org.postgresql.jdbc.PgConnection@... on thread main, stack trace follows java.lang.Exception: Apparent connection leak detected
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:99) ~[HikariCP-7.0.2.jar:?]
means:
• HikariCP handed out a JDBC connection (PgConnection@...) to some code.
• That code never returned the connection to the pool (i.e., it didn’t close it).
• After Hikari’s leak‑detection timeout, Hikari logs this stack trace to show where getConnection() was called but the connection was not closed.
In Airbyte terms, this usually indicates that some part of the code path using the Postgres connection is not closing it properly, but the provided forum posts and issues only show timeouts and “connection is not available” errors, not this specific leak‑detection message. [Sync shows 0 records; Failed to connect external DB]
Because there’s no direct mention of this leak error in the knowledge sources, I can’t point you to a known bug or configuration fix in a specific Airbyte version. To move forward, you’d typically:
• Look at the full stack trace Hikari prints after this line to see which Airbyte class/method called getConnection() and didn’t close it.
• Use that to decide whether it’s:
◦ A known bug (then upgrade Airbyte / the connector), or
◦ A custom connector / custom code path you control that needs to ensure every acquired connection is closed in all code paths (including error cases).
If you can share the full stack trace around this message (with class names and line numbers), I can help you interpret which part of Airbyte is involved, but I still won’t be able to reference a specific documented fix unless it appears in the provided knowledge sources. 👍 0 button 👎 0 button ℹ️ Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.Amal Mokhtar
03/12/2026, 12:51 PMAmal Mokhtar
03/12/2026, 12:53 PMWarning from destination: sourceStats must be set with recordCount for state message id=1 and my postgres connector is 3.7.2kapa.ai
03/12/2026, 12:53 PMsourceStats with a recordCount value:
> “It is expected that a source will always populate the source stats attribute in a state message. The source stats is the count of records associated with the state message…” [ClickHouse NPE; Partner destinations]
When this is missing, destinations (including Postgres 3.x) can throw errors like:
• sourceStats must be set with recordCount for state message id=1
• or NPEs when sourceStats is null. [ClickHouse NPE]
From the docs/issues we have:
• This is enforced on the destination side, but it is caused by the state messages emitted by the source.
• The ClickHouse issue shows that if a source emits state without sourceStats, bulk destinations fail. [ClickHouse NPE]
• The general protocol docs only describe state as a black box and don’t mention sourceStats explicitly, so there is no version matrix telling us exactly from which Postgres source version this is guaranteed to be present. [State & checkpointing]
Because of that, I cannot say with certainty, from the provided docs, whether source-postgres 3.7.2 is supposed to always set sourceStats.recordCount or whether you’re hitting a bug in that version.
What the docs do support is:
1. The destination is correct to expect sourceStats.recordCount on each state message. [Partner destinations]
2. Your warning means at least one state message from the Postgres source is missing that field.
Given the limitations of the knowledge sources, the best supported steps are:
• Inspect the job logs to confirm that the state messages from the Postgres source lack sourceStats or recordCount (this matches the pattern in the ClickHouse issue). [ClickHouse NPE]
• If you are not running a custom fork of the source, this likely needs to be raised as a bug against source-postgres 3.7.2, referencing:
◦ The error text, and
◦ The requirement that sources populate sourceStats.recordCount for each state. [Partner destinations]
The provided docs do not contain a configuration toggle or workaround on the destination side to bypass this check, so any real fix has to be in the source’s state emission logic. 👍 0 button 👎 0 button ℹ️ Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.Amal Mokhtar
03/12/2026, 1:00 PMkapa.ai
03/12/2026, 1:00 PMsource-postgres:3.7.2 is emitting a state without the required stats.
From the destination requirements:
• Destinations must treat state as checkpoints and
• Must append record counts to the source’s state message before emitting it. [Partner destinations]
For this to work, the source must provide sourceStats.recordCount on every state message. When it doesn’t, bulk destinations (like Postgres 3.x) fail with errors such as:
> sourceStats must be set with recordCount for state message id=1
This exact pattern is documented for another destination (ClickHouse): a custom source emitted state without sourceStats, and the destination threw an error / NPE because sourceStats was missing. [ClickHouse NPE]
So, in your case:
• Destination: destination-postgres:3.0.7 (Direct Load, bulk CDK)
• Source: source-postgres:3.7.2
• Meaning of the warning: At least one state message from source-postgres is missing sourceStats.recordCount, which the destination now requires.
The provided docs do not say:
• From which source-postgres version sourceStats.recordCount is guaranteed to be set, or
• Whether 3.7.2 has a known bug around this.
So I can’t point to a specific “upgrade/downgrade to version X” fix from the knowledge sources.
What you can do, based on the available information:
1. Confirm the missing stats in logs
Inspect the sync logs and look for the raw state messages; you should see that the state with id=1 has no sourceStats or no recordCount. This matches the ClickHouse example. [ClickHouse NPE]
2. If you’re using a custom/forked source
Update it so that every emitted state message includes:
◦ sourceStats
◦ sourceStats.recordCount = number of records associated with that state.
1. If you’re using the standard source-postgres:3.7.2 image
The docs don’t provide a workaround or config flag on destination-postgres to bypass this check. Since the requirement is that sources populate sourceStats.recordCount, this likely needs to be treated as a bug report against source-postgres 3.7.2, referencing:
◦ The error text, and
◦ The documented requirement that destinations rely on record counts in state messages. [Partner destinations]
Because the knowledge sources don’t include a compatibility matrix or a specific fix for this version pair, I can’t recommend an exact version combination as a guaranteed solution; the core, documented requirement is that the source must emit state with sourceStats.recordCount, and your error indicates that is not happening. 👍 0 button 👎 0 button ℹ️ Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.