"list index out of range" with Cloudflare - any ideas?

Trying to enable Cloudflare, but getting this error when attempting to update records.

list index out of range

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 134, in handle_call_service
    connection.context(msg),
  File "/usr/src/homeassistant/homeassistant/core.py", line 1226, in async_call
    await asyncio.shield(self._execute_service(handler, service_call))
  File "/usr/src/homeassistant/homeassistant/core.py", line 1253, in _execute_service
    await self._hass.async_add_executor_job(handler.func, service_call)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/cloudflare/__init__.py", line 50, in update_records_service
    _update_cloudflare(cfupdate, email, key, zone, records)
  File "/usr/src/homeassistant/homeassistant/components/cloudflare/__init__.py", line 67, in _update_cloudflare
    update_records = cfupdate.get_recordInfo(headers, zoneid, zone, records)
  File "/usr/local/lib/python3.7/site-packages/pycfdns/__init__.py", line 56, in get_recordInfo
    recordInfoResponse = recordInfoRequest.json()['result'][0]
IndexError: list index out of range

My configuration is:

cloudflare:
  email: !secret email
  api_key: !secret cloudflare_apikey
  zone: myhostname.com
  records:
    - sub1
    - sub2
    - route2

(redacted values, obviously)

The API key is correct.

Is your cloudflare_apikey wrapped in quotes in the secrets.yaml file?

pycfdns is coming back with no results…so either api key isn’t right, zone isn’t right, or records aren’t right.

Try changing the log level to debug for this in configuration.yaml

# Example configuration.yaml entry
logger:
  default: warning
  logs:
    homeassistant.components.cloudflare: debug

You should see the following logs appear when you force an update:

_LOGGER.debug("Starting update for zone %s", zone)


_LOGGER.debug("Header data defined as: %s", headers)


_LOGGER.debug("Zone ID is set to: %s", zoneid)

----- WILL CRASH HERE SO WONT SEE THE FOLLOWING ----

_LOGGER.debug("Records: %s", update_records)


_LOGGER.debug("Update for zone %s is complete", zone)

These might not be that useful…but who knows.

Maybe try a single record at a time…it could only be one that is failing.

Looks good to me. Here’s what I have

2020-02-05 08:00:11 DEBUG (SyncWorker_11) [homeassistant.components.cloudflare] Starting update for zone zozobrado.com
2020-02-05 08:00:11 DEBUG (SyncWorker_11) [homeassistant.components.cloudflare] Header data defined as: {'X-Auth-Email': '{email}', 'X-Auth-Key': '{apikey}', 'Content-Type': 'application/json'}
2020-02-05 08:00:11 DEBUG (SyncWorker_11) [homeassistant.components.cloudflare] Zone ID is set to: {the correct Zone ID}
2020-02-05 08:00:12 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.139859816021136] list index out of range
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 134, in handle_call_service
    connection.context(msg),
  File "/usr/src/homeassistant/homeassistant/core.py", line 1226, in async_call
    await asyncio.shield(self._execute_service(handler, service_call))
  File "/usr/src/homeassistant/homeassistant/core.py", line 1253, in _execute_service
    await self._hass.async_add_executor_job(handler.func, service_call)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/cloudflare/__init__.py", line 50, in update_records_service
    _update_cloudflare(cfupdate, email, key, zone, records)
  File "/usr/src/homeassistant/homeassistant/components/cloudflare/__init__.py", line 67, in _update_cloudflare
    update_records = cfupdate.get_recordInfo(headers, zoneid, zone, records)
  File "/usr/local/lib/python3.7/site-packages/pycfdns/__init__.py", line 56, in get_recordInfo
    recordInfoResponse = recordInfoRequest.json()['result'][0]
IndexError: list index out of range

It successfully discovered my zone key. But then failed right after that.

I removed all but one, new, entry. And it’s still failing. :confused:

Is there anyway to get an output of the return data? That could provide some clues. “Debug” isn’t as verbose as I’d like (I’d like to see the HTTP request URL and Headers, and Raw Response body).

My calls look fine - I don’t know what calls the component is doing:

## Request
curl "https://api.cloudflare.com/client/v4/zones/{same zone id}" \
     -H 'X-Auth-Key: {api key}' \
     -H 'X-Auth-Email: {email}'

Returns:

{
  "result": {
    "id": "{same zone id}",
    "status": "active",
  // [ ...  snipped ...]
  },
  "success": true,
  "errors": [],
  "messages": []
}

It is just using the python cloudflare library.

https://gitlab.com/ludeeus/pycfdns/-/blob/master/pycfdns/init.py

It calls get_zoneID() then calls get_recordInfo() with this zoneID.

From what I can tell, it will generate a URL like this:

https://api.cloudflare.com/client/v4/zones/<zoneID>/dns_records?name=<record.zone>

So if you take your zoneID for each record that it returns and fill in the <record.zone> and use your header, you should be able to see what that returns with curl.

https://api.cloudflare.com/client/v4/zones/<zoneID>/dns_records?name=sub1.myhostname.com

Ah ha! That’s the clue! The component does not compensate for new records.

That’s where it was failing. I had a list, to debug how it “looks” in CF after HA runs. I thought it would create new entities for those not found. My list consisted of two manually added ones, and a new entry.

I have removed the “new” entry (only need the two right now), and it now works!

Thanks, @jocnnor. With your help, I was able to track down where and why it was failing.