Skip to content

[Aurora Postgres 17][Bug?] INSERT ON CONFLICT against parent table works, but logs error with invalid ON CONFLICT clause

0

[Aurora Postgres 17][Bug?] INSERT ON CONFLICT against parent table works, but logs error with invalid ON CONFLICT clause

Instance Family Class: db.t4g
PostgreSQL 17.5 on x86_64-pc-linux-gnu, compiled by x86_64-pc-linux-gnu-gcc (GCC) 10.5.0, 64-bit

Hi there,

I'm facing an buggy error entry in the instance logs when using INSERT ON CONFLICT statement inside a trigger against a partitioned table.

The flow is relatively simple: we stream changes to a table from a subscription, and we have an AFTER TRIGGER FOR EACH ROW to transform the data into another table.

The thing is that the INSERT happens successfully in the background, but the instance logs have several entries with the following error:

2026-04-10 20:36:58 UTC:10.255.170.206(46020):auditlogs_app@auditlogs:[26449]:ERROR:  there is no unique or exclusion constraint matching the ON CONFLICT specification
2026-04-10 20:36:58 UTC:10.255.170.206(46020):auditlogs_app@auditlogs:[26449]:STATEMENT:  
	INSERT INTO audit_logs (
	    producer,
...
		project_id
	) VALUES ( ....)
	ON CONFLICT (producer, local_id) -- ???
	DO NOTHING

The reason I'm thinking is a buggy entry is due to the following:

  • I've tested the same scenario locally, with the same Postgres community version, no errors shown.
  • The subscription has the disable_on_error = true flag set, so it should stop/disable the subscription activity. However, replication continues working correctly.
  • I tested adding a bug in the trigger (which makes the trigger fail), and the subscription gets disabled correctly. That leads me to think that the error in the logs is bugged.
  • The expansion in the ON CONFLICT clause, does not match with the function's definition.
  • The INSERT happens in the background correctly.

Here are the parts relevant to this case:

CREATE TABLE IF NOT EXISTS audit_logs (
    producer         VARCHAR                     NOT NULL,
    local_id         BIGINT                      NOT NULL,
    created_at       TIMESTAMPTZ                 NOT NULL,
...
    CONSTRAINT audit_logs_pkey PRIMARY KEY (created_at, producer, local_id)
) PARTITION BY RANGE (created_at);

CREATE TABLE IF NOT EXISTS audit_logs_y2025m03 PARTITION OF audit_logs
    FOR VALUES FROM ('2025-03-01 00:00:00+00') TO ('2025-04-01 00:00:00+00');
CREATE UNIQUE INDEX IF NOT EXISTS audit_logs_y2025m03_producer_local_id_uidx ON audit_logs_y2025m03 (producer, local_id);

Trigger definition:

CREATE OR REPLACE FUNCTION insert_into_audit_logs()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO public.audit_logs (
        producer,
        local_id,
        environment_id, 
...
        ingested_at
    ) VALUES (
        'producer',                                         -- producer
        NEW.id,                                            -- id
...
        NOW()                                              -- ingested_at
    )
    ON CONFLICT (created_at, producer, local_id) DO NOTHING;
    -- Also tried the following, same error output in the logs:
    --ON CONFLICT ON CONSTRAINT audit_logs_pkey DO NOTHING;

    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trigger_insert_into_audit_logs ON origin_table_streamed;

CREATE TRIGGER trigger_insert_into_audit_logs
AFTER INSERT ON origin_table_streamed
FOR EACH ROW
EXECUTE FUNCTION insert_into_audit_logs();

ALTER TABLE origin_table_streamed ENABLE ALWAYS TRIGGER trigger_insert_into_audit_logs;

Cheers,

asked a month ago33 views
1 Answer
0

Based on the behavior you're describing, this appears to be related to how logical replication handles INSERT ON CONFLICT statements in Aurora PostgreSQL, rather than a bug with the statement itself.

When using logical replication with subscriptions, there's a known limitation where the ON CONFLICT clause isn't fully supported in certain contexts. Native PostgreSQL logical replication can't detect data conflicts from multiple publishers or replicated modifications that conflict with locally changed data. When replication workers process changes, they may log errors even when the underlying operation completes successfully.

The fact that your INSERT is succeeding in the background while generating error logs is consistent with how logical replication handles conflict scenarios. The replication process attempts to apply the change, encounters what it perceives as a conflict situation, logs the error, but the actual data operation may still complete through PostgreSQL's normal conflict resolution mechanisms.

A few points to consider:

  1. The error logging behavior in logical replication contexts can differ from direct SQL execution, which explains why you don't see this error when testing locally outside of a replication scenario.

  2. The disable_on_error flag may not trigger for this specific type of logged error if the underlying transaction ultimately succeeds, which aligns with your observation that replication continues working.

  3. The error message about "no unique or exclusion constraint matching the ON CONFLICT specification" in the logs may be generated during the replication worker's processing phase, even though the constraint exists and works correctly for direct operations.

To work around this, you might consider restructuring your trigger logic to handle potential conflicts differently, or review whether the logical replication setup requires adjustments to how conflicts are managed. You could also check the PostgreSQL logs for more detailed context about when these errors occur in relation to the replication worker processes.
Sources
Troubleshoot Aurora PostgreSQL logical replication issues | AWS re:Post
Aurora PostgreSQL-Compatible integration with remote PostgreSQL databases - AWS Prescriptive Guidance

answered a month ago
EXPERT
reviewed a month ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.