@@ -271,6 +271,23 @@ func getCreateDNSRecordParam(cfc cloudFlareChange) cloudflare.CreateDNSRecordPar
271271 }
272272}
273273
274+ func convertCloudflareError (err error ) error {
275+ var apiErr * cloudflare.Error
276+ if errors .As (err , & apiErr ) {
277+ if apiErr .ClientRateLimited () || apiErr .StatusCode >= http .StatusInternalServerError {
278+ // Handle rate limit error as a soft error
279+ return provider .NewSoftError (err )
280+ }
281+ }
282+ // This is a workaround because Cloudflare library does not return a specific error type for rate limit exceeded.
283+ // See https://github.com/cloudflare/cloudflare-go/issues/4155 and https://github.com/kubernetes-sigs/external-dns/pull/5524
284+ // This workaround can be removed once Cloudflare library returns a specific error type.
285+ if strings .Contains (err .Error (), "exceeded available rate limit retries" ) {
286+ return provider .NewSoftError (err )
287+ }
288+ return err
289+ }
290+
274291// NewCloudFlareProvider initializes a new CloudFlare DNS based Provider.
275292func NewCloudFlareProvider (domainFilter endpoint.DomainFilter , zoneIDFilter provider.ZoneIDFilter , proxiedByDefault bool , dryRun bool , regionKey string , customHostnamesConfig CustomHostnamesConfig , dnsRecordsConfig DNSRecordsConfig ) (* CloudFlareProvider , error ) {
276293 // initialize via chosen auth method and returns new API object
@@ -335,14 +352,7 @@ func (p *CloudFlareProvider) Zones(ctx context.Context) ([]cloudflare.Zone, erro
335352
336353 zonesResponse , err := p .Client .ListZonesContext (ctx )
337354 if err != nil {
338- var apiErr * cloudflare.Error
339- if errors .As (err , & apiErr ) {
340- if apiErr .ClientRateLimited () || apiErr .StatusCode >= http .StatusInternalServerError {
341- // Handle rate limit error as a soft error
342- return nil , provider .NewSoftError (err )
343- }
344- }
345- return nil , err
355+ return nil , convertCloudflareError (err )
346356 }
347357
348358 for _ , zone := range zonesResponse .Result {
@@ -753,14 +763,7 @@ func (p *CloudFlareProvider) listDNSRecordsWithAutoPagination(ctx context.Contex
753763 for {
754764 pageRecords , resultInfo , err := p .Client .ListDNSRecords (ctx , cloudflare .ZoneIdentifier (zoneID ), params )
755765 if err != nil {
756- var apiErr * cloudflare.Error
757- if errors .As (err , & apiErr ) {
758- if apiErr .ClientRateLimited () || apiErr .StatusCode >= http .StatusInternalServerError {
759- // Handle rate limit error as a soft error
760- return nil , provider .NewSoftError (err )
761- }
762- }
763- return nil , err
766+ return nil , convertCloudflareError (err )
764767 }
765768
766769 for _ , r := range pageRecords {
@@ -788,15 +791,11 @@ func (p *CloudFlareProvider) listCustomHostnamesWithPagination(ctx context.Conte
788791 for {
789792 pageCustomHostnameListResponse , result , err := p .Client .CustomHostnames (ctx , zoneID , resultInfo .Page , cloudflare.CustomHostname {})
790793 if err != nil {
791- var apiErr * cloudflare.Error
792- if errors .As (err , & apiErr ) {
793- if apiErr .ClientRateLimited () || apiErr .StatusCode >= http .StatusInternalServerError {
794- // Handle rate limit error as a soft error
795- return nil , provider .NewSoftError (err )
796- }
794+ convertedError := convertCloudflareError (err )
795+ if ! errors .Is (convertedError , provider .SoftError ) {
796+ log .Errorf ("zone %q failed to fetch custom hostnames. Please check if \" Cloudflare for SaaS\" is enabled and API key permissions, %v" , zoneID , err )
797797 }
798- log .Errorf ("zone %q failed to fetch custom hostnames. Please check if \" Cloudflare for SaaS\" is enabled and API key permissions, %v" , zoneID , err )
799- return nil , err
798+ return nil , convertedError
800799 }
801800 for _ , ch := range pageCustomHostnameListResponse {
802801 chs [newCustomHostnameIndex (ch )] = ch
0 commit comments