Skip to content

[source-google-ads] Syncs hang indefinitely on 403 errors in v4.1.4 due to streaming decoder issue #72820

@devin-ai-integration

Description

@devin-ai-integration

Connector Name

source-google-ads

Connector Version

4.1.4

What step the error happened?

During the sync

Relevant information

After upgrading to version 4.1.4, full refresh syncs are getting stuck indefinitely instead of completing or failing. The syncs run for many hours (6+ hours) when they normally complete in ~15 minutes.

Root Cause Analysis:

Version 4.1.4 introduced a change from paginated API endpoints (googleAds:search) to streaming endpoints (googleAds:searchStream), along with a new GoogleAdsStreamingDecoder. The error handler in manifest.yaml is configured to IGNORE 403 errors:

base_error_handler:
  type: DefaultErrorHandler
  response_filters:
    - type: HttpResponseFilter
      action: IGNORE
      http_codes:
        - 403

This IGNORE action was designed to skip inaccessible customer accounts. However, with streaming responses, when a 403 error occurs:

  1. The GoogleAdsStreamingDecoder attempts to parse the error response as JSON data
  2. The decoder's _buffer_up_to_limit method calls response.iter_content() which may block or return unexpected data
  3. The IGNORE action doesn't properly terminate the stream
  4. This causes the sync to hang indefinitely with repeated "Error sending heartbeat" warnings

Observed Behavior:

  • Sync starts and reads some records successfully (e.g., from campaign_basic stream)
  • Then encounters HTTP Status Code: 403. Error: Forbidden. You don't have permission to access this resource. errors
  • Sync becomes stuck with 0 bytes/records synced and repeated heartbeat errors
  • Previous syncs on version 4.1.3 and earlier completed successfully

Affected Streams:
This appears to affect GAQL-based streams and full refresh syncs in particular.

Suggested Fix:
Either:

  1. Change the 403 error action from IGNORE to FAIL to properly terminate the sync
  2. Or update the GoogleAdsStreamingDecoder to properly handle error responses when the IGNORE action is triggered

Workaround:
Pin the connector to version 4.1.3 or earlier.

Relevant log output

[timestamp] info: HTTP Status Code: 403. Error: Forbidden. You don't have permission to access this resource.
[timestamp] info: HTTP Status Code: 403. Error: Forbidden. You don't have permission to access this resource.
[timestamp] warn: Error sending heartbeat
[timestamp] warn: Error sending heartbeat
[timestamp] warn: Error sending heartbeat
... (repeats indefinitely)

Contribute

  • Yes, I want to contribute

Internal Tracking: https://github.com/airbytehq/oncall/issues/11152

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions