The provided ssh_keys value must be an array.

February 18, 2019 598 views
API Automated Setups Ghost Python Ubuntu 18.04

I’m receiving The provided ssh_keys value must be an array., and I’ve tried various dumping of the array of ssh key ids. using API attribute described in https://developers.digitalocean.com/documentation/v2/#create-a-new-droplet.

# list of numbers
print(type(key_ids), key_ids)
<class 'list'> [12345678, 12345678]

# stringified list via `str()` or via `json.dumps()`
<class 'str'> [12345678, 12345678]

# mapping each value to string, seems unlikely since ids are returned as numbers when creating droplets… but trying many things anyway. via `list(map(lambda k: str(k), [12345678, 12345678]))`
<class 'list'> ['12345678', '12345678']

The payload looks like:

{
        'name': 'mydropletname',
        'region': 'sfo2',
        'size': '4gb',
        'image': 'ghost-18-04',
        'ssh_keys': <variations of above>
}

And I’m using the following endpoint: https://api.digitalocean.com/v2/droplets

3 Answers
traumalligator May 26, 2019
Accepted Answer

ok, figured it out! the issue is with formatting the params. it has to be like 'ssh_keys[]': [123] instead of 'ssh_keys': [123].

Hey friend,

You’ll want to get the ID for the SSH key by listing the keys first:
https://developers.digitalocean.com/documentation/v2/#list-all-keys

From there just plug it in like this:

"ssh_keys":[19402414],

Here’s a curl string I just ran, with the API key removed, which did the job:

curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer [removed]" -d '{"name":"example.com","region":"nyc3","size":"s-1vcpu-1gb","image":"ubuntu-16-04-x64","ssh_keys":[19402414],"backups":false,"ipv6":true,"user_data":null,"private_networking":null,"volumes": null,"tags":["web"]}' "https://api.digitalocean.com/v2/droplets" 

Jarland

  • thanks for the reply @jarland! but I am already doing that. I just replaced the ids with 12345678 for example sake.

    example code

    def get_key_ids(token):
        """get a key to embed when making a new droplet."""
    
        headers = {
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json'
        }
    
        request = requests.get('https://api.digitalocean.com/v2/account/keys', headers=headers)
    
        return list(map(lambda key: key['id'], request.json()['ssh_keys']))
    
    def deploy_droplet(token):
        """deploy a new droplet"""
    
        headers = {
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json'
        }
    
        droplet_info = {
            'name': 'exampledroplet',
            'region': 'sfo2',
            'size': '4gb',
            'image': 'ghost-18-04',
            'ssh_keys': get_key_ids(token)
        }
    
        print('deploying new droplet…')
        url = 'https://api.digitalocean.com/v2/droplets'
        request = requests.post(url, headers=headers, params=droplet_info)
    
        # see https://github.com/requests/requests/blob/master/requests/status_codes.py
        # pylint: disable=E1101
        if request.status_code != requests.codes.accepted:
            print('Something went wrong. ' + request.json()['message'])
            return
    
        print('Deployed!')
    

following up; it also doesnt appear as if using the SSH key fingerprints matters either. for example replacing the above example’s get_key_ids method with:

def get_key_fingerprints(token):
    """
    Using ssh_key fingerprints because array of ids seems broken on Digital
    Ocean's side?
    """

    request = requests.get('https://api.digitalocean.com/v2/account/keys', headers=headers(token))

    return list(map(lambda key: key['fingerprint'], request.json()['ssh_keys']))

doesnt effect things either.

also! if you do 'ssh_keys': [] it isnt rejected, but any string or number value (whether valid ids/fingerprints or not!) give the exact same error message. is this because Digital Ocean doesnt want to reveal whether or not youre using a proper ID for security purposes???

Have another answer? Share your knowledge.