Okay, I am severely puzzled. There are only three places in the code which could result in the error you're seeing. Here is one. The second one is called here, and the last one is called here. One of these is causing the issue. What that means, however, is that you have an API call that is not returning the expected data.
It should not be possible for those API calls to not have the 'indices'
key:
$ python3
Python 3.6.4 (default, Mar 26 2018, 19:37:24)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import elasticsearch
>>> client = elasticsearch.Elasticsearch()
>>> client.indices.create('foo')
{'acknowledged': True, 'shards_acknowledged': True}
>>> client.indices.stats(index='foo', metric='store,docs')
{'_shards': {'total': 10, 'successful': 5, 'failed': 0}, '_all': {'primaries': {'docs': {'count': 0, 'deleted': 0}, 'store': {'size_in_bytes': 650, 'throttle_time_in_millis': 0}}, 'total': {'docs': {'count': 0, 'deleted': 0}, 'store': {'size_in_bytes': 650, 'throttle_time_in_millis': 0}}}, 'indices': {'foo': {'primaries': {'docs': {'count': 0, 'deleted': 0}, 'store': {'size_in_bytes': 650, 'throttle_time_in_millis': 0}}, 'total': {'docs': {'count': 0, 'deleted': 0}, 'store': {'size_in_bytes': 650, 'throttle_time_in_millis': 0}}}}}
>>> client.indices.stats(index='foo', metric='store,docs').keys()
dict_keys(['_shards', '_all', 'indices'])
>>> client.indices.stats(index='foo', metric='store,docs')['indices']
{'foo': {'primaries': {'docs': {'count': 0, 'deleted': 0}, 'store': {'size_in_bytes': 650, 'throttle_time_in_millis': 0}}, 'total': {'docs': {'count': 0, 'deleted': 0}, 'store': {'size_in_bytes': 650, 'throttle_time_in_millis': 0}}}}
>>> client.cluster.state(index='foo', metric='metadata')['metadata']['indices']
{'foo': {'state': 'open', 'settings': {'index': {'creation_date': '1523285826585', 'number_of_shards': '5', 'number_of_replicas': '1', 'uuid': 'uSjJoCSPRFq4b9Mbyg8K5w', 'version': {'created': '5030099'}, 'provided_name': 'foo'}}, 'mappings': {}, 'aliases': [], 'primary_terms': {'0': 1, '1': 1, '2': 1, '3': 1, '4': 1}, 'in_sync_allocations': {'2': ['6D5FrZKeTiSRe9uwXAXrkQ'], '3': ['jHndJWgHSmO1XZdbg8eKUA'], '4': ['AzWYz7PiQo-H4D_wwUW-fQ'], '1': ['SOAQ7qAWSMWult-EDH6GvA'], '0': ['KsiZ37XlSDOUSH0BPz5NQg']}}}
>>> client.indices.segments(index='foo')['indices']
{'foo': {'shards': {'0': [{'routing': {'state': 'STARTED', 'primary': True, 'node': 'uNe7JnzBSDqbhbl7s-x_oQ'}, 'num_committed_segments': 0, 'num_search_segments': 0, 'segments': {}}], '1': [{'routing': {'state': 'STARTED', 'primary': True, 'node': 'uNe7JnzBSDqbhbl7s-x_oQ'}, 'num_committed_segments': 0, 'num_search_segments': 0, 'segments': {}}], '2': [{'routing': {'state': 'STARTED', 'primary': True, 'node': 'uNe7JnzBSDqbhbl7s-x_oQ'}, 'num_committed_segments': 0, 'num_search_segments': 0, 'segments': {}}], '3': [{'routing': {'state': 'STARTED', 'primary': True, 'node': 'uNe7JnzBSDqbhbl7s-x_oQ'}, 'num_committed_segments': 0, 'num_search_segments': 0, 'segments': {}}], '4': [{'routing': {'state': 'STARTED', 'primary': True, 'node': 'uNe7JnzBSDqbhbl7s-x_oQ'}, 'num_committed_segments': 0, 'num_search_segments': 0, 'segments': {}}]}}}
All that this is showing is that on a clean node, with no indices to start, I create an empty index, and still get the 'indices'
key back, just like those calls are making. Something really weird is going on if any one of these API calls is not able to find the indices
key. To be further clear that this is in unusual territory, this code is heavily tested by Travis CI across all supported minor releases of Elasticsearch with Curator running each of Python 2.7, 3.5, and 3.6 and I cannot make it fail in the way you are seeing. (And yes, I can see that you're on 6.2.3, and my latest iteration is on 6.2.2, but that level of API change should not exist in a patch release).
Is there something else about your cluster that I should know about? Where/how is it hosted? How is Curator installed?