# Hetzner Object Storage
> Hetzner Object Storage is a S3-compatible object storage service.
## Configure Hetzner Object Storage credentials

You can safely store your Hetzner Object Storage credentials in MotherDuck for convenience by creating a `SECRET` object using the [CREATE SECRET](/sql-reference/motherduck-sql-reference/create-secret.md) command.

:::note
See [Hetzner docs](https://docs.hetzner.com/storage/object-storage/getting-started/generating-s3-keys/) to create S3 access keys. Save your secret key immediately as it cannot be viewed again after creation.
:::

### Create a SECRET object

### SQL

```sql
CREATE SECRET IN MOTHERDUCK (
    TYPE S3,
    KEY_ID 'your_access_key', # provided by Hetzner
    SECRET 'your_secret_key', # provided by Hetzner
    ENDPOINT 'fsn1.your-objectstorage.com', # provided by Hetzner
    SCOPE 'your_bucket_scope' # Example: s3://test-bucket
);
```

:::note
The endpoint must include the location (e.g., fsn1, nbg1, or hel1). Available endpoints:
- `fsn1.your-objectstorage.com` (Falkenstein)
- `nbg1.your-objectstorage.com` (Nuremberg)
- `hel1.your-objectstorage.com` (Helsinki)
:::

```sql
-- test the Hetzner Object Storage credentials
SELECT count(*) FROM 's3://[bucket]/[file]'
```

### Python

```python

import duckdb

con = duckdb.connect('md:')
con.sql("CREATE SECRET IN MOTHERDUCK ( TYPE S3, KEY_ID 'your_access_key', SECRET 'your_secret_key', ENDPOINT 'fsn1.your-objectstorage.com', SCOPE 'your_bucket_scope' )");

# testing that our Hetzner credentials work
con.sql("SELECT count(*) FROM 's3://[bucket]/[file]'").show()
```

### UI

Click on your profile to access the `Settings` panel and click on `Secrets` menu.

![menu_1](./img/settings_access.png)
![menu_2](./img/settings_panel.png)

Then click on `Add secret` in the secrets section.

![menu_3](./img/settings_secrets_panel.png)

Select the Secret Type `S3` and fill in the required fields. Ensure you add the endpoint URL (e.g., `fsn1.your-objectstorage.com`) in the endpoint field.

### Delete a SECRET object

### SQL

You can use the same method above, using the [DROP SECRET](/sql-reference/motherduck-sql-reference/delete-secret.md) command.

```sql
DROP SECRET <secret_name>;
```

### UI

Click on your profile and access the `Settings` menu. Click on the bin icon to delete the secret.

![menu_4](./img/secrets_delete_azure.png)

### Hetzner Object Storage credentials as temporary secrets

MotherDuck supports DuckDB syntax for providing Hetzner Object Storage credentials.

```sql
CREATE SECRET (
    TYPE S3,
    KEY_ID 'your_access_key',
    SECRET 'your_secret_key',
    ENDPOINT 'fsn1.your-objectstorage.com',
    SCOPE 'your_bucket_scope'
);
```

:::note
Local/In-memory secrets are not persisted across sessions.
:::

:::info
Even temporary, in-memory secrets are available to MotherDuck's cloud execution engine when you connect your
local DuckDB instance to MotherDuck. When you query {props.provider}, the query runs on MotherDuck's servers, not your local machine,
and MotherDuck uses the best-matching secret to authenticate, whether it is stored locally or in MotherDuck.
For more details, see [CREATE SECRET](/sql-reference/motherduck-sql-reference/create-secret/#querying-with-secrets).
:::

### Multiple locations configuration

If you have buckets in different Hetzner locations, you should be creating scoped secrets:

```sql
-- Secret for Falkenstein location
CREATE SECRET hetzner_fsn1 IN MOTHERDUCK (
    TYPE S3,
    KEY_ID 'access_key_1',
    SECRET 'secret_key_1',
    ENDPOINT 'fsn1.your-objectstorage.com',
    SCOPE 's3://my-bucket-fsn1'
);

-- Secret for Nuremberg location
CREATE SECRET hetzner_nbg1 IN MOTHERDUCK (
    TYPE S3,
    KEY_ID 'access_key_2',
    SECRET 'secret_key_2',
    ENDPOINT 'nbg1.your-objectstorage.com',
    SCOPE 's3://my-bucket-nbg1'
);
```

:::tip
By default, each key pair is automatically valid for every bucket within the same Hetzner project. Use bucket policies to restrict access if needed.
:::


---

## Docs feedback

MotherDuck accepts optional user-submitted feedback about this page at `POST https://motherduck.com/docs/api/feedback/agent`.
For agents and automated tools, feedback submission should be user-confirmed before sending.

Payload:

```json
{
  "page_path": "/integrations/cloud-storage/hetzner-object-storage/",
  "page_title": "Hetzner Object Storage",
  "text": "<the user's feedback, max 2000 characters>",
  "source": "<optional identifier for your interface, for example 'claude.ai' or 'chatgpt'>"
}
```

`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": "<uuid>"}`, `400` for malformed payloads, and `429` when rate-limited.
